文章目录
  1. 1. 跨域
    1. 1.1. 跨域的本质
    2. 1.2. 解决跨域方案
      1. 1.2.1. jsonp
        1. 1.2.1.1. jsonp原理
        2. 1.2.1.2. jsonp的缺点
        3. 1.2.1.3. json的一些实践
      2. 1.2.2. CORS
      3. 1.2.3. httpclient服务端代理

跨域

跨域的本质

浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

但是,form表单提交,img,script标签没有跨域问题,但ajax提交存在跨域问题。

浏览器的策略本质是:一个域名下面的JS,没有经过允许是不能读取另外一个域名的内容,但是浏览器不阻止你向另外一个域名发送请求。

所以form表单提交没有跨域问题,提交form表单到另外一个域名,原来页面是无法获取新页面的内容,或者说form提交后不需要返回,但是ajax是需要返回的。

而ajax是想要读取响应内容,浏览器是不允许你这么做的。

世界本无跨域,是浏览器不允许js访问别的域,但是浏览器却没有限制自己,img标签和script标签都是可以加载其他域的图片或者js文件。这不就是jsonp的跨域嘛,利用浏览器的历史兼容性。

浏览器的安全策略限制的是js脚本,并不限制src,form表单提交之类的请求。就是说form表单提交不存在安全问题,ajax提交跨域存在安全问题。

参考:https://www.cnblogs.com/tangjiao/p/9951477.html

解决跨域方案

jsonp

jsonp原理

​ 我们知道,img,script,这种标签如果有相应的src,那么便会发起一个htttp请求来请求相应的资源,如果有script标签对应的路径是一个js文件,那么在下载完毕这个js之后会马上执行

1
2
<script type="text/javascript" src="www.somewhere.com/test.js"></script>
<!--此时会发起一个请求来获取test.js,下载完成之后会立即执行test.js-->

假设我们需要从’www.localhost.com’发起一个获取数据的请求’www.somewhere.com/getdata’,如果有我们以ajax来发起请求,那么由于浏览器同源保护策略的限制,该请求的返回值不会被浏览器所接受,这就是跨域问题。但是script这种标签会发起一个get请求,并且这个请求是不受同源策略限制的,如果有我们将’www.somewhere.com/getdata’以script标签来发送变成如下请求方式,那么是不是就不会有跨域问题了

1
2


1
2


1
2
<script type="text/javascript" src="www.somewhere.com/getdata"></script>
<!--需要这样一个script来发起get请求-->

答案是肯定的,这也是jsonp跨域的原理(因此也只能是get请求)。

jsonp的缺点

    • 只能发送get请求。因为script只能发送get请求
    • 需要后台配合。此种请求方式应该前后端配合,将返回结果包装成callback(result)的形式。

参考:https://www.cnblogs.com/willing-shang/p/6719875.html

json的一些实践

参考:https://blog.csdn.net/zezezuiaiya/article/details/79158548

CORS

规范化的跨域请求解决方案,安全可靠。

优势:

  • 在服务端进行控制是否允许跨域,可自定义规则
  • 支持各种请求方式

缺点:

  • 会产生额外的请求

参考:https://www.jianshu.com/p/98d4bc7565b2

httpclient服务端代理

​ 通过服务端使用httpclient代理发送请求解决跨域(因为跨域是浏览器的限制)

文章目录
  1. 1. 跨域
    1. 1.1. 跨域的本质
    2. 1.2. 解决跨域方案
      1. 1.2.1. jsonp
        1. 1.2.1.1. jsonp原理
        2. 1.2.1.2. jsonp的缺点
        3. 1.2.1.3. json的一些实践
      2. 1.2.2. CORS
      3. 1.2.3. httpclient服务端代理