解决跨域

  1. JSONP: 利用script标签立即下载并执行的特性,就可以在回调函数中拿到返回来的数据。
// 1.回调函数
function handleResponse(data){
    console.log(data);
}
// 2.动态创建 script 
var script = document.createElement('script');
script.src = 'http://test.com/json?callback=handleResponse';
document.body.insertBefore(script,document.body.firstChild);

缺点:

  1. 仅限于GET请求
  2. 有安全问题,万一有恶意代码返回,前端无法阻止
  3. 无法检测请求是否成功
  1. CORS: CORS是跨域资源共享(Cross-origin resource sharing), 利用这个技术关键是在于服务端,设置返回的Access-Control-Allow-Origin响应头允许跨域操作。

发送请求时有两种情况:

  • 简单请求

方法: GET、HEAD、POST
Content-Type的值:text/plain、multipart/form-data、application/x-www-form-urlencoded

发起简单请求,浏览器判断是简单请求的话就会在请求头添加origin字段,值是发起请求的所在的源。服务端收到请求后会判断origin是否在自己的许可范围,如果不在就拒绝,如果在就会有以下的响应头添加:

  • Access-Control-Allow-Origin(必选):告诉客户端我接受请求,值为origin的值,若允许所有源请求就会返回 *。
  • Access-Control-Allow-Credentials(可选):告诉浏览器发送请求时携带Cookie,true表示允许false表示禁止。
  • Access-Control-Expose-Headers(可选):额外给客户端返回的头部字段。
  • 复杂请求

复杂请求会有两次,第一次是发送一个预检请求,使用的方法是options,询问服务器是否允许我进行跨域请求资源。并且允许客户端自定义请求头的类型,询问服务器是否允许。

 Origin: http://test.com
 Access-Control-Request-Method: PUT
 Access-Control-Request-Headers: Custom-Header1,Custom-Header2
 Host: target.com
 Accept-Language: en-US
 Connection: keep-alive
User-Agent: Mozilla/5.0...

然后服务器会进行验证,还会在响应头进行说明允许你的请求。

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61(Unix)
Access-Control-Allow-Origin: http://test.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Custom-Header1,Custom-Header2
Access-Control-Max-Age: 1728000
Content-type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
  • Access-Control-Allow-Origin:告诉客户端,允许你这个源的请求
  • Access-Control-Allow-Methods:告诉客户端,服务端允许的跨域 AJAX 请求的类型,也可进行 GET 或者 POST 请求
  • Access-Control-Allow-Headers:告诉客户端,服务端允许的发送请求时的自定义请求头
  • Access-Control-Max-Age: 告诉客户端预检请求的有效期,省去了多次的预检请求。也就是说,1728000 秒内你可以直接发送真正的 AJAX 请求,不用每次询问
  1. Nginx代理: 将nginx目录下的nginx.conf修改,通过反向代理的方式来实现跨域请求。
# /所有以apis开头发起的请求会被分发到myserver
location ^~ /apis/ {
     proxy_pass http://myserver; # 负载均衡名,写你请求的服务器地址
     proxy_set_header X-real-ip $remote_addr;
     proxy_set_header Host $http_host;
}
  1. document.domain: 该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式,只需要给页面添加 document.domain = ‘test.com’ 表示二级域名都相同就可以实现跨域。

  2. window.name: 页面如果设置了window.name,那么在不关闭页面的情况下,即使进行了页面跳转location.href=…,这个window.name还是会保留。

// 打开必应 https://www.bing.com/
// 打开控制台
> window.name
""
> window.name='test';
"test"
> location.href='http://www.google.com';
"http://www.google.com"
Navigated to https://www.google.com/
> window.name
"test"
  1. postMessage+iframe: 这种方式通常用于获取嵌入页面中的第三方页面数据。一个页面发送消息,另一个页面判断来源并接收消息。

postMessage(data,origin)方法接受两个参数:

  • data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化。
  • origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以把参数设置为”*”,这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/“。
    03 小结
// 发送消息端
<div>
   <div id="color">Frame Color</div>
</div>
<div>
   <iframe id="child" src="http://b.com/b.html"></iframe>
</div>

window.onload=function(){
   window.frames[0].postMessage('getcolor','http://b.com');
}
// 接收消息端
window.addEventListener('message',function(e){
      console.log(e)
},false);

备注: 参考http://blog.alanwu.website/2020/03/06/crossOrigin/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值