目录

前端数据请求方式总结前端数据请求方式,原生JS发送请求,-axios,-jQuery-AJAX,同源策略,跨域

前端数据请求方式总结(前端数据请求方式,原生JS发送请求, axios, jQuery AJAX,同源策略,跨域)

前端数据请求方式总结

1. 前端数据请求方式

发请求方式请求方法缺陷
formGET、POST刷新页面或新开页面
aGET刷新页面或新开页面
imgGET以图片展示,需要加载一张图片
linkGET以CSS、favicon形式展示
scriptGET只能以JS脚本运行,JSONP原理
  1. <form> 使用 form 表单的 action 向指定 url 发请求,会刷新页面或新开页面。
  2. <a> 使用 <a> 标签的 href 属性发__GET__请求,会刷新页面或新开页面。
  3. <img> 使用 <img> 标签的 src 属性发__GET__请求,只能以图片形式展示。
  4. <link> 使用 <link> 标签的 href 属性发__GET__请求,只能以CSS、favicon 的形式展示
  5. <script> 使用 <script> 标签的 src 属性发__GET__请求,只能以脚本形式运行,JSONP

2. 原生JS发送请求

2.1 XMLHttpRequest 对象

重点: XMLHttpRequest 对象用来在浏览器和服务器之间进行数据传输

使用 XMLHttpRequest 对象,首先需要生成一个实例。

    let request = new XMLHttpRequest();
1. request.open(method,url,async)用来开启数据传输通路

三个参数分别对应:

  • method:请求的方法,可以是GET、PPST、PUT、DELETE等
  • url:请求的路径
  • async:是否异步,默认为true,就是异步。false 为同步,可能造成浏览器阻塞。
2. request.send()

request.send()用来向请求路径发送数据。当请求有数据发送时,参数为所发送的数据。

同步请求会等全部响应完毕再返回,异步请求直接返回该方法。

3. readyState属性

readyState属性返回一个 XMLHttpRequest 代理当前所处的状态。

状态描述
0UNSENT代理被创建,但尚未调用 open() 方法。
1OPENEDopen() 方法已经被调用。
2HEADERS_RECEIVEDsend() 方法已经被调用,并且头部和状态已经可获得。
3LOADING下载中; responseText 属性已经包含部分数据。
4DONE下载操作已完成。
4. onreadystatechange属性

onreadystatechange属性监听 readyState 的值(监听 XMLHttpRequest代理的状态),当值发生变化(状态变化),对不同的状态执行相应的回调函数。

以上4个方法/属性就可以完成一个AJAX的请求

5. request.setRequestHeader()方法

request.setRequestHeader()方法:在发送请求之前设置请求头,对应http请求的第二部分。

    request.setRequestHeader('Content-Type','x-www-form-urlencoded')
6. request.responseText 属性

request.responseText 属性就是 AJAX 中后端返回的数据,一般是 JSON 格式的字符串。

2.2 使用xhr发起GET请求

步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 调用 xhr.send() 函数
  4. 监听 xhr.onreadystatechange 事件
    <script>
      // 1. 创建 xhr 对象
      const xhr = new XMLHttpRequest();
      //   console.log(xhr);

      //   2.监听 xhr.onreadystatechange 事件
      xhr.addEventListener('load', function () {
        // 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 status
        if (xhr.status === 200) {
          //打印服务器响应回来的数据
          console.log(xhr.responseText);
        }
      });
      // 3.调用 xhr.open() 函数
      xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks?id=1');
      // 4.调用 xhr.send() 函数
      xhr.send();
    </script>

2.3 使用xhr发起POST请求

步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 设置 Content-Type 属性(固定写法)
  4. 调用 xhr.send() 函数,同时指定要发送的数据
  5. 监听 xhr.onreadystatechange 事件
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
// 3. 设置 Content-Type 属性(固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 4. 调用 send(),同时将数据以查询字符串的形式,提交给服务器
xhr.send('bookname=水浒传&author=施耐庵&publisher=天津图书出版社')
// 5. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText)
    }
}

2.4 封装自己的Ajax函数

    <script>
      // 封装自己的Ajax函数

      // data对象:我们需要把data函数中的对象 转化为字符串对象,从而提交给服务器 因此我们要resloveData函数:
      // resloveData()思路先定义一个数组 ;然后循环数组data中的元素,并将元素通过push方法将键值对压进我们新定义的数组中;循环结束后将元素用户&连接
      function resolveData(data) {
        let arr = [];
        for (let k in data) {
          arr.push(k + '=' + data[k]);
          console.log(k + '=' + data[k]);
        }
        return arr.join('&');
      }
      var test = resolveData({ name: '张三', age: 18 });
      console.log(test);

      function myAjax(optins) {
        const xhr = new XMLHttpRequest();
        // 调用resolveData()函数并指定一个变量来接收拼接好的字符串
        const val = resolveData(optins.data);
        // xhr添加监听事件然后获取附属器上的数据
        xhr.onreadystatechange = function () {
          if (xhr.readyState == 400 && xhr.status == 200) {
            var res = JSON.parse(xhr.responseText);
            options.success(result);
            // 判断请求的类型
            if (options.method.toUpperCase() == 'GET') {
              // 发起get请求
              xhr.open('GET', 'optioms.URL?s');
              xhr.send();
            } else if (options.method.toUpperCase() == 'POST') {
              // 发起post请求
              xhr.send('POST', 'options.URL');
              xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
              xhr.send(val);
            }
          }
        };
      }
    </script>

3. axios

3.1 axios发起GET请求

axios.get('url', { params: { /*参数*/ } }).then(callback)

具体的请求示例如下:

// 请求的 URL 地址
 var url = 'http://www.liulongbin.top:3006/api/get'
 // 请求的参数对象
 var paramsObj = { name: 'zs', age: 20 }
 // 调用 axios.get() 发起 GET 请求
 axios.get(url, { params: paramsObj }).then(function(res) {
     // res.data 是服务器返回的数据
     var result = res.data
     console.log(res)
 })

3.2 axios发起POST请求

axios.post('url', { /*参数*/ }).then(callback)

具体的请求示例如下:

// 请求的 URL 地址
 var url = 'http://www.liulongbin.top:3006/api/post'
 // 要提交到服务器的数据
 var dataObj = { location: '北京', address: '顺义' }
 // 调用 axios.post() 发起 POST 请求
 axios.post(url, dataObj).then(function(res) {
     // res.data 是服务器返回的数据
     var result = res.data
     console.log(result)
 })

3.3 直接使用axios发起请求

axios 也提供了类似于 jQuery 中 $.ajax() 的函数,语法如下:

 axios({
     method: '请求类型',
     url: '请求的URL地址',
     data: { /* POST数据 */ },
     params: { /* GET参数 */ }
 }) .then(callback)
1. 直接使用axios发起GET请求
 axios({
     method: 'GET',
     url: 'http://www.liulongbin.top:3006/api/get',
     params: { // GET 参数要通过 params 属性提供
         name: 'zs',
         age: 20
     }
 }).then(function(res) {
     console.log(res.data)
 })
2. 直接使用axios发起POST请求
axios({
     method: 'POST',
     url: 'http://www.liulongbin.top:3006/api/post',
     data: { // POST 数据要通过 data 属性提供
         bookname: '程序员的自我修养',
         price: 666
     }
 }).then(function(res) {
     console.log(res.data)
 })

4. jQuery AJAX

4.1 jQuery AJAX发起GET请求

<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js"></script>
<script>
$(document).ready(function(){
  $("button").click(function(){
    $.get("http://www.liulongbin.top:3006/api/get",function(data,status){
      alert("数据:" + data + "\n状态:" + status);
    });
  });
});
</script>
</head>
<body>

<button>向页面发送 HTTP GET 请求然后获得返回的结果</button>

</body>
</html>

4.2 jQuery AJAX发起POST请求

<!DOCTYPE html>
<html>
<head>
<script src="/jquery/jquery-1.11.1.min.js">
</script>
<script>
$(document).ready(function(){
  $("button").click(function(){
    $.post("http://www.liulongbin.top:3006/api/post",
    {
      name:"Donald Duck",
      city:"Duckburg"
    },
    function(data,status){
      alert("数据:" + data + "\n状态:" + status);
    });
  });
});
</script>
</head>
<body>

<button>向页面发送 HTTP POST 请求并获得返回的结果</button>

</body>
</html>

4. 同源策略

  • 协议相同

  • 域名相同

  • 端口相同

    非同源的网站会受到下列限制:

  • Cookie、LocalStorage 和 IndexDB 无法读取。

  • DOM 无法获得

  • AJAX 请求不能发送。(或者是请求发送之后,浏览器识别出不同源,将响应拦截了)

    因为有同源策略的限制,当需要请求外部网站的数据时,就需要跨域。

5. 跨域

由于浏览器同源策略,AJAX 不能访问不同源的资源。这时候,就需要 跨域

关于同源策略现阶段一般用两种方法跨域:

1. JSONP 跨域原理

JSONP的最基本的原理是:动态添加一个 <script> 标签,而script标签的src属性是没有跨域的限制的。

  1. 事先在请求方页面中写定一个 callback 函数,用来获取响应方响应的数据。
  2. 在请求方页面中动态创建 <script> 标签,通过设置 <script> 标签的 src 属性对 src 指向的网站发起请求。
  3. 需要将 1 中的 callback 函数名以查询参数的形式写入 2 中 <script> 标签的 src 中,告知后端要执行的回调函数
  4. 响应方获得请求,返回一段JS代码(该段JS代码执行事先写好的 callback 函数,并将__要返回的数据作为 callback 函数的参数带入请求方__)
  5. 这时候,请求方就通过 callback 函数获得了请求的数据。

在实际使用中,通过两个约定来规范 JSONP 的使用:

  • 使用查询参数指明 callback 的函数名,形如 ?callback=函数名
  • 查询参数中的函数名一般随机生成,使用完毕即删除,保证不污染全局变量。

JSOPN跨域请求例子:

function JSONP(path){
        // 创建一个 script 标签
        let script = document.createElement("script") 
        
        // 随机生成回调函数名
        let functionName = 'callback' + parseInt(Math.random()*100000,10)
        // 定义回调函数,处理获得的数据
        window[functionName] = function(data){
            console.log('获取的数据是:')
            console.log(data) 
            alert('请求成功。')
        }
        // 设置JSONP请求路径
        script.src = path + "?callback=" + functionName
        // 将 script 标签插入到页面中
        document.body.appendChild(script)
        // 请求完成之后,删除回调函数,节约内存
        delete window[functionName]
    }

2. CORS(Cross-origin resource sharing)跨域资源共享

CORS 是解决跨域数据请求的终极解决方案

原理:CORS 跨域的使用方式是在后端代码中设置响应头,将响应资源的响应头设置成请求页面的源(间接使要响应的资源与请求同源)

response.setHeader('Access-Control-Allow-Origin', '发送请求的源地址')