Ajax基础

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Ajax 是 Asynchronous JavaScript and XML异步 JavaScript 和 XML的简写

Ajax 中的异步可以异步地向服务器发送请求在等待响应的过程中不会阻塞当前页面浏览器可以做自己的事情。直到成功获取响应后浏览器才开始处理响应数据 

XML可扩展标记语言是前后端数据通信时传输数据的一种格式而现在比较常用的是JSON 

Ajax 其实就是浏览器与服务器之间的一种异步通信方式 

使用 Ajax 可以在不重新加载整个页面的情况下对页面的某部分进行更新 

  • 慕课网注册检测
  • 慕课网搜索提示 

搭建Ajax开发环境

Ajax 需要服务器环境非服务器环境下很多浏览器无法正常使用 Ajax个人使用phpstudy

Ajax的基本用法

Ajax 想要实现浏览器与服务器之间的异步通信需要依靠 XMLHttpRequest它是一个构造函数 

不论是 XMLHttpRequest还是 Ajax都没有和具体的某种数据格式绑定 

Ajax的使用步骤

  • 1创建xhr对象
  • 2监听事件处理响应
  • 3准备发送请求
  • 4发送请求
// 2.Ajax 的使用步骤
    // 2.1.创建 xhr 对象
    const xhr = new XMLHttpRequest();

    // 2.2.监听事件处理响应
    // 当获取到响应后会触发 xhr 对象的 readystatechange 事件可以在该事件中对响应进行处理

    // xhr.addEventListener('readystatechange', () => {}, false);

    xhr.onreadystatechange = () => {
       if (xhr.readyState !== 4) return;

    //   // HTTP CODE
    //   // 获取到响应后响应的内容会自动填充 xhr 对象的属性
    //   // xhr.statusHTTP  200 404
    //   // xhr.statusTextHTTP 状态说明 OK Not Found
       if ((xhr.status >= 200) & (xhr.status < 300) || xhr.status === 304) {
         // console.log('正常使用响应数据');
         console.log(xhr.responseText);
       }
    };

    // readystatechange 事件也可以配合 addEventListener 使用不过要注意IE6~8 不支持 addEventListener
    // 为了兼容性readystatechange 中不使用 this而是直接使用 xhr
    // 由于兼容性的原因最好放在 open 之前

    // 2.3.准备发送请求
    // xhr.open(
    //   'HTTP 方法 GET、POST、PUT、DELETE',
    //   '地址 URL https://www.imooc.com/api/http/search/suggest?words=js ./index.html ./index.xml ./index.txt',
    //   true
    // );

    // 调用 open 并不会真正发送请求而只是做好发送请求前的准备工作

    // 2.4.发送请求
    // 调用 send() 正式发送请求

    // send() 的参数是通过请求体携带的数据 如果是get请求 参数为null为了兼容性也可以不写不建议
    // xhr.send(null);

readystatechange 事件监听 readyState 这个状态的变化,它的值从 0 ~ 4一共 5 个状态

  • 0未初始化。尚未调用 open()
  • 1启动。已经调用 open()但尚未调用 send()
  • 2发送。已经调用 send()但尚未接收到响应
  • 3接收。已经接收到部分响应数据 
  • 4完成。已经接收到全部响应数据而且已经可以在浏览器中使用了
// 3.使用 Ajax 完成前后端通信
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
        if (xhr.readyState !== 4) return;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
            console.log(xhr.responseText);
            console.log(typeof xhr.responseText);
        }
    };
    xhr.open('GET', url, true);
    xhr.send(null);

GET请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
 <!--<form action="https://www.imooc.com/api/http/search/suggest?words=js" method="get">
      <input type="text" name="username" />
      <input type="password" name="password" />
      <input type="submit" value="提交" />
 </form>-->
<script>
  // 1.携带数据
  // GET 请求不能通过请求体携带数据但可以通过请求头携带
  // const url =
  //   'https://www.imooc.com/api/http/search/suggest?words=js&username=alex&age=18';
  // const xhr = new XMLHttpRequest();

  // xhr.onreadystatechange = () => {
  //   if (xhr.readyState != 4) return;

  //   if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //     console.log(xhr.responseText);
  //   }
  // };

  // xhr.open('GET', url, true);

  // xhr.send(null);

  // 不会报错但不会发送数据
  // xhr.send('sex=male');

  // 2.数据编码
  // 如果携带的数据是非英文字母的话比如说汉字就需要编码之后再发送给后端不然会造成乱码问题
  // 可以使用 encodeURIComponent() 编码
  const url = `https://www.imooc.com/api/http/search/suggest?words=${encodeURIComponent(
          '前端'
  )}`;
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = () => {
    if (xhr.readyState !== 4) return;

    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.responseText);
    }
  };

  xhr.open('GET', url, true);

  xhr.send(null);
</script>
</body>
</html>

注意事项ajax的get请求与form表单get请求相似只不过form表单get请求action属性后面不能加参数加了也没用看下面截图就明白了相当于没加 

POST请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>POST 请求</title>
</head>
<body>
<!--<form
        action="https://www.imooc.com/api/http/search/suggest?words=js"
        method="post"
>
  <input type="text" name="username" />
  <input type="password" name="password" />
  <input type="submit" value="提交" />
</form>-->

<script>
  // 1.携带数据
  // POST 请求主要通过请求体携带数据同时也可以通过请求头携带
  const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = () => {
    if (xhr.readyState != 4) return;

    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.responseText);
    }
  };

  xhr.open('POST', url, true);

  // 如果想发送数据直接写在 send() 的参数位置一般是字符串
  xhr.send('username=alex&age=18');

  // 不能直接传递对象需要先将对象转换成字符串的形式
  // xhr.send({
  //   username: 'alex',
  //   age: 18
  // });
  // [object Object]

  // 2.数据编码
  // xhr.send(`username=${encodeURIComponent('张三')}&age=18`);
</script>
</body>
</html>

注意事项ajax的post请求与form表单post请求相似form表单post请求action属性后面可以加参数看下面截图就明白了

JSON(JAVASCRIPT OBJECT NOTATION)

JSON(js对象表示法)是Ajax发送和接收数据的一种格式

JSON有3种形式每种形式的写法都和JS中的数据类型很像可以很轻松的和JS中的数据类型互相转换  JS->JSON->Java/PHP 

  • 简单值形式 对应着JS中的基本数据类型数字、字符串、布尔值、null
  • JSON中没有undefined值 JSON中字符串必须使用双引号 JSON中不能注释
  • 对象形式 JSON 的对象形式就对应着 JS 中的对象
  • JSON 中对象的属性名必须用双引号属性值如果是字符串也必须用双引号 JSON 中只要涉及到字符串就必须使用双引号 不支持 undefined
  • 数组形式 JSON 的数组形式就对应着 JS 中的数组
  • 数组中的字符串必须用双引号 JSON 中只要涉及到字符串就必须使用双引号 不支持 undefined
const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = () => {
    if (xhr.readyState != 4) return;

    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.responseText);
      console.log(typeof xhr.responseText);
    }
  };

  // xhr.open('GET', './plain.json', true);
  // xhr.open('GET', './obj.json', true);
  xhr.open('GET', './arr.json', true);

  xhr.send(null);

JSON.parse()将json格式的字符串转化为js中对应的数据类型

JSON.stringify()将js中对应的数据类型转化为json格式的字符串

使用JSON.parse()和JSON.stringify()封装localStorage

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>JSON 的常用方法</title>
</head>
<body>
<script type="module">
  // 1.JSON.parse()
  // JSON.parse() 可以将 JSON 格式的字符串解析成 JS 中的对应值
  // 一定要是合法的 JSON 字符串否则会报错
  // const xhr = new XMLHttpRequest();

  // xhr.onreadystatechange = () => {
  //   if (xhr.readyState != 4) return;
  //
  //   if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //     console.log(xhr.responseText);
  //     console.log(typeof xhr.responseText);
  //
  //     console.log(JSON.parse(xhr.responseText));
  //     console.log(JSON.parse(xhr.responseText).data);
  //   }
  // };

  // // xhr.open('GET', './plain.json', true);
  // // xhr.open('GET', './obj.json', true);
  // xhr.open('GET', './arr.json', true);

  // xhr.open(
  //   'GET',
  //   'https://www.imooc.com/api/http/search/suggest?words=js',
  //   true
  // );

  // xhr.send(null);

  // 2.JSON.stringify()
  // JSON.stringify() 可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串
  // console.log(
  //   JSON.stringify({
  //     username: 'alex',
  //     age: 18
  //   })
  // );

  // const xhr = new XMLHttpRequest();
  //
  // xhr.open(
  //   'POST',
  //   'https://www.imooc.com/api/http/search/suggest?words=js',
  //   true
  // );
  // xhr.send(
  //   JSON.stringify({
  //     username: 'alex',
  //     age: 18
  //   })
  // );

  // 3.使用 JSON.parse() 和 JSON.stringify() 封装 localStorage
  import { get, set, remove, clear } from './storage.js';

  set('username', 'alex');
  console.log(get('username'));

  set('zs', {
    name: '张三',
    age: 18
  });
  console.log(get('zs'));

  remove('username');
  clear();
</script>
</body>
</html>
const storage = window.localStorage;

// 设置
const set = (key, value) => {
  // {
  //   username: 'alex'
  // }
  storage.setItem(key, JSON.stringify(value));
};

// 获取
const get = key => {
  // 'alex'
  // {
  //   "username": "alex"
  // }
  return JSON.parse(storage.getItem(key));
};

// 删除
const remove = key => {
  storage.removeItem(key);
};

// 清空
const clear = () => {
  storage.clear();
};

export { set, get, remove, clear };

 

跨域

不同域只要协议/域名/端口号任何一个不一样就是不同域

阻止跨域请求其实是浏览器本身的一种安全策略--同源策略

其他客户端或服务器都不存在跨域被阻止的问题

跨域解决方案(了解即可)

  • CORS跨域资源共享优先使用
  • JSONP
const url='https://www.imooc.com/api/http/search/suggest?words=js'
    const xhr=new XMLHttpRequest();
    xhr.onreadystatechange=()=>{
      if (xhr.readyState!==4) return;
      if ((xhr.status>=200&&xhr.status<300)||xhr.status===304){
        console.log(xhr.responseText);
      }
    }
    xhr.open('GET',url,true);
    xhr.send(null);

    // Access-Control-Allow-Origin: *
    // 表明允许所有的域名来跨域请求它* 是通配符没有任何限制

    // 只允许指定域名的跨域请求
    // Access-Control-Allow-Origin: http://127.0.0.1:5500

    // 2.使用 CORS 跨域的过程
    // ① 浏览器发送请求
    // ② 后端在响应头中添加 Access-Control-Allow-Origin 头信息
    // ③ 浏览器接收到响应
    // ④ 如果是同域下的请求浏览器不会额外做什么这次前后端通信就圆满完成了
    // ⑤ 如果是跨域请求浏览器会从响应头中查找是否允许跨域访问
    // ⑥ 如果允许跨域通信圆满完成
    // ⑦ 如果没找到或不包含想要跨域的域名就丢弃响应结果

    // 3.CORS 的兼容性
    // IE10 及以上版本的浏览器可以正常使用 CORS

    // https://caniuse.com/

    // JSONP
<script>
// 1.JSONP 的原理
      // script 标签跨域不会被浏览器阻止
      // JSONP 主要就是利用 script 标签加载跨域文件

      // 2.使用 JSONP 实现跨域
      // 服务器端准备好 JSONP 接口
      // https://www.imooc.com/api/http/jsonp?callback=handleResponse

      // 手动加载 JSONP 接口或动态加载 JSONP 接口
      const script = document.createElement('script');
      script.src =
        'https://www.imooc.com/api/http/jsonp?callback=handleResponse';
      document.body.appendChild(script);

      // 声明函数
      const handleResponse = data => {
        console.log(data);
      };


      // 优先使用 CORS如果浏览器不支持 CORS 的话再使用 JSONP
    </script>
    <!-- <script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script> -->
    <!-- 相当于 -->
    <!-- <script>
      handleResponse({
        code: 200,
        data: [
          {
            word: 'jsp'
          },
          {
            word: 'js'
          },
          {
            word: 'json'
          },
          {
            word: 'js 入门'
          },
          {
            word: 'jstl'
          }
        ]
      });
</script>

XHR的属性

  • responseType和response属性
  • timeout属性(设置请求的超时时间ms)
  • withCredentials属性

xhr.responseType='json' 浏览器会帮我们自动调用JSON.parse(xhr.response)给它转换成这种类型也就是说服务器返回给我们的是JSON格式的字符串不可能直接把js对象返回过来

// 1.responseType 和 response 属性 IE6~9 不支持IE10 开始支持
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
    const xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
      if (xhr.readyState != 4) return;

      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
    //     // 文本形式的响应内容
    //     // responseText 只能在没有设置 responseType 或者 responseType = '' 或 'text' 的时候才能使用
    //     console.log('responseText:', xhr.responseText);

    //     // 可以用来替代 responseText
        console.log('response:', xhr.response);
    //     console.log(JSON.parse(xhr.responseText));
      }
    };
    xhr.open('GET', url, true);

    // // xhr.responseType = '';
    // // xhr.responseType = 'text';
    xhr.responseType = 'json';

    xhr.send(null);
    

xhr.timeout=10  出错变红了请求被取消了因为规定的时间内超时没有完成

// 2.timeout 属性
    // 设置请求的超时时间单位 ms
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
    const xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
      if (xhr.readyState != 4) return;

      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
        console.log(xhr.response);
      }
    };

    xhr.open('GET', url, true);

    xhr.timeout=10;
    // xhr.timeout = 10000;

    xhr.send(null);

    // IE6~7 不支持IE8 开始支持

使用 Ajax 发送请求默认情况下同域时会携带 Cookie跨域时不会携带Cookie要携带的话得设置xhr.withCredentials = true; 但是最终能否成功跨域携带 Cookie还要看服务器同不同意

XHR的方法

  • abort() 终止当前请求
  • setRequestHeader()

当同时书写xhr.open('POST',url,true)post请求xhr.send('username=alex&age=18')携带参数才有必要加上xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')

请求头中的Content-Type字段用来告诉服务器浏览器发送的数据是什么格式的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>XHR 的方法</title>
</head>
<body>
 <!--<form
  action="https://www.imooc.com/api/http/search/suggest?words=js"
  method="post"
>
  <input type="text" name="username" />
  <input type="password" name="password" />
  <input type="submit" value="提交" />
</form>-->

<script>
  // 1.abort()
  // 终止当前请求
  // 一般配合 abort 事件一起使用
  // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  //
  // const xhr = new XMLHttpRequest();
  //
  // xhr.onreadystatechange = () => {
  //   if (xhr.readyState != 4) return;
  //
  //   if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //     console.log(xhr.response);
  //   }
  // };
  //
  // xhr.open('GET', url, true);
  //
  // xhr.send(null);
  //
  // xhr.abort();

  // 2.setRequestHeader()
  // 可以设置请求头信息
  // xhr.setRequestHeader(头部字段的名称, 头部字段的值);
  // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  const url = 'https://www.imooc.com/api/http/json/search/suggest?words=js';

  const xhr = new XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState != 4) return;

    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.response);
    }
  };
  xhr.open('POST', url, true);
  //
  // // 请求头中的 Content-Type 字段用来告诉服务器浏览器发送的数据是什么格式的
  // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.setRequestHeader('Content-Type', 'application/json');
  // // xhr.send(null);
  // xhr.send('username=alex&age=18');
  xhr.send(
          JSON.stringify({
            username: 'alex'
          })
  );
</script>
</body>
</html>

XHR的事件

  • load事件响应数据可用时触发
  • error事件请求发生错误时触发
  • abort事件终止当前请求触发
  • timeout事件 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>XHR 的事件</title>
</head>
<body>
<script>
  // 1.load 事件
  // 响应数据可用时触发
  // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  // const xhr = new XMLHttpRequest();

  // // xhr.onload = () => {
  // //   if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  // //     console.log(xhr.response);
  // //   }
  // // };
  // xhr.addEventListener(
  //   'load',
  //   () => {
  //     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //       console.log(xhr.response);
  //     }
  //   },
  //   false
  // );

  // xhr.open('GET', url, true);

  // xhr.send(null);

  // IE6~8 不支持 load 事件

  // 2.error 事件
  // 请求发生错误时触发

  // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  // const url = 'https://www.iimooc.com/api/http/search/suggest?words=js';
  // const xhr = new XMLHttpRequest();

  // xhr.addEventListener(
  //   'load',
  //   () => {
  //     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //       console.log(xhr.response);
  //     }
  //   },
  //   false
  // );
  // xhr.addEventListener(
  //   'error',
  //   () => {
  //     console.log('error');
  //   },
  //   false
  // );

  // xhr.open('GET', url, true);

  // xhr.send(null);

  // IE10 开始支持

  // 3.abort 事件
  // 调用 abort() 终止请求时触发
  // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

  // const xhr = new XMLHttpRequest();

  // xhr.addEventListener(
  //   'load',
  //   () => {
  //     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  //       console.log(xhr.response);
  //     }
  //   },
  //   false
  // );
  // xhr.addEventListener(
  //   'abort',
  //   () => {
  //     console.log('abort');
  //   },
  //   false
  // );

  // xhr.open('GET', url, true);

  // xhr.send(null);

  // xhr.abort();

  // IE10 开始支持

  // 4.timeout 事件
  // 请求超时后触发
  const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

  const xhr = new XMLHttpRequest();

  xhr.addEventListener(
          'load',
          () => {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
              console.log(xhr.response);
            }
          },
          false
  );
  xhr.addEventListener(
          'timeout',
          () => {
            console.log('timeout');
          },
          false
  );

  xhr.open('GET', url, true);

  xhr.timeout = 10;

  xhr.send(null);

  // IE8 开始支持
</script>
</body>
</html>

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6