zoukankan      html  css  js  c++  java
  • 细说Ajax跨域

    一、什么是跨域

      跨域问题来自于浏览器同源策略的限制,包括DOM同源限制和Ajax同源限制,本文探讨的是Ajax跨域。Ajax跨域指的是一个页面的Ajax只能请求和当前页面同源的数据,如果发现请求到的数据不符合要求,浏览器就会阻止返回的数据。所谓同源,指的是协议、域名、端口号都必须完全相同(同一IP的不同域名也是跨域)。同源策略的主要目的是防止CSRF攻击,它可以有效地避免由于恶意攻击带来的危险,浏览器同源策略使得网络访问更加安全。

      但是,实际开发与生产中,常常获取使用来自其他站点的资源,这时候就需要发起跨域请求,也就需要使用特殊的方法来处理,使得我们能够获得想要的数据。由此可知,跨域仅限于浏览器中,是由于浏览器对不同源数据的拦截产生的,跨域有时候是不可避免的,我们需要采取措施实现跨域请求。

    二、跨域构成条件

    • 浏览器限制:浏览器本身限制跨域
    • 跨域请求:发起的请求是跨域的
    • XHR(XMLHttpRequest)类型:请求类型是XHR请求

      由上可知,解决跨域问题可以从上面三个方面着手,只需解决其一,则跨域问题也就不存在了。

    三、跨域问题解决方案

    • 浏览器限制方式

      解决浏览器限制的方式可以通过命令:

      C:Program Files (x86)GoogleChromeApplicationchrome.exe --disable-web-security --user-data-dir=E:chrome.log来解除浏览器默认的Web安全限制;这里使用chrome浏览器做了解释。

    • 跨域请求方式

      CORS

      CORS中文是“跨域资源共享”(Cross-origin resource sharing),是W3C支持的一种新的跨域方式,它与其它的方式不同的是,它是写入标准的跨域请求方式,现代浏览器普遍支持。它允许在服务器支持的前提之下,像发起普通ajax请求一样发送跨域请求。除了get请求CORS支持其它种类请求。

      CORS请求分为简单请求和非简单请求两种,简单请求需要满足以下两个条件:

        1)请求方法是以下三种方法之一:

      • HEAD
      • GET
      • POST

        2)HTTP的头信息不超出以下几种字段:

      • Accept
      • Accept-Language
      • Content-Language
      • Last-Event-ID
      • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

      除此之外都是复杂请求,对于简单请求和复杂请求浏览器的处理方式不同。

      对于简单请求,浏览器会在请求头中添加Origin字段来指明本次请求源,服务器会对发来的请求进行检查,对于符合条件的请求,服务器会在返回头信息中添加Access-Control-Allow-开头的相关字段。

      对于非简单请求,正式请求之前会增加一次OPTIONS请求来进行”预检”,此次请求会带上请求源,服务器会校验是否符合条件,如果不符合会返回一个不带任何CORS相关的头信息字段,浏览器就会知道请求不允许,触发错误,停止继续发送请求。

      CORS重点就在服务器上,只要配置了允许CORS,就可以正常发送请求,非常方便且安全性好,具体的服务器配置取决于服务端的不同实现。

      服务器代理

      这是一种终极的解决方案,因为限制只存在于浏览器中,在其他环境下是不存在的,服务器中自然也不存在,所以只需要在服务器做好请求代理,请求变成同源(请求方式变成同源的请求,但资源依旧是跨域获取的)的自然就不存在问题了。

    • XHR类型

        JSONP

      首先最有名的一种方式就是JSONP,在学习JSONP之前首先要知道虽然浏览器有同源限制,但是有三个标签是不符合这种限制的<img>标签的src(获取图片)属性,<link>的href(获取css)属性,<script>的src(获取javascript)属性,这是由他们的自身特性所决定的。而JSONP则是利用了script标签不限制同源的特点来实现的、也就是说JSONP发出的不是XHR请求,而是script请求。

      JSONP原理:

        1.JSONP发送的请求是script请求,区别于XHR请求,不存在跨域的问题。

        2. 普通的XHR请求返回的是JSON数据对象,JSONP返回的是一个JS脚本。

        3. 请求URL的不同,请求带有callback字段

      清楚了JSONP的原理之后,再看JSONP其实很简单了,下面来看一个简单的小例子。

      假设客户端需要获取的JSON数据{code: 200, data: “success”},一个简单的服务端实现如下(使用node.js原生http模块)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const http = require('http');
    const url = require('url');
     
    http.createServer((req, res) => {
    if (req.url.startsWith('/test')) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    const callback = url.parse(req.url, true).query.callback;
    const result = '{code: 200, data: "success"}';
    const jsonpCallback = `${callback}(${result})`
    res.end(jsonpCallback);
    }
    }).listen(8888);

    客户端的请求如下

    1
    2
    3
    4
    5
    6
    7
    <script>
    function jsonpCallback (res) {
    // 在这里处理请求结果
    console.log(res);
    }
    </script>
    <script src="http://127.0.0.1:8888/test?callback=jsonpCallback"></script>

      综合客户端和服务端的代码可以看出,在客户端,通过请求参数传递一个JSONP方法名,在服务器端,返回的结果使用指定的JSONP方法调用来包装,这样相当于请求了一段JS,而真正的返回结果可以通过函数调用参数来获取,这样就可以绕开浏览器同源限制,获取跨域请求结果。

    JSONP是一种常用的跨域方式,目前有很多前端的JSONP请求封装,它们通过通过动态创建script标签来实现,我们可以直接调用。JSONP方式兼容所有的浏览器,但是只支持get请求。

      JSONP弊端

    1. 服务器端需要改动。
    2. 只支持GET方法。
    3. 发送的不是XHR请求,无法使用各种XHR各种优势。
  • 相关阅读:
    python中的zip()函数和map()函数
    Unity3d插件推荐
    使用Unity3d的Physics.Raycast()的用法做子弹射击
    Unity3D集成SVN进行版本控制
    WVGA-维基百科
    Unity3D之如何创建正确的像素比在屏幕上
    Unity3D如何获取对象和子对象
    Thread: BooleanRT : Realtime 3D boolean operations for (Runtime,Editor)
    Unity3D GUI中的图片跟随鼠标旋转脚本
    三维软件转Unity的系统单位设置研究
  • 原文地址:https://www.cnblogs.com/julygift/p/8535450.html
Copyright © 2011-2022 走看看