跨域怎么解决

发布时间:2023年12月26日
跨域解决主要有以下?种:
  • JSONP
  • CORS
  • Nginx代理
  • document.domain
  • window.name
  • postMessage+iframe

1.JSONP

我们知道写 HTML 代码的时候,加?图?链接就不会有获取不到图?的问题。这是因为图
?资源并没有进? ajax 请求,?且 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);
利? script 标签?即下载并执?的特性,我们就可以在回调函数中拿到返回来的数据。那
么是不是所有的情况都可以呢?显然不是的。虽然实现是?较简单的操作,但是有缺点:
1. 仅限于 GET 请求
2. 有安全问题,万?有恶意代码返回,前端?法阻?
3. ?法检测请求是否成功

2.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 ,询问服务器是
否允许我进?跨域请求资源。并且允许客户端?定义请求头的类型,询问服务器是否允
许。
OPTIONS /cors HTTP/1.1
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 请求,不?每次询问

3.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;
}

4.document.domain

该?式只能?于?级域名相同的情况下,?如 a.test.com b.test.com 适?于该?式。
只需要给??添加 document.domain = 'test.com' 表??级域名都相同就可以实现跨域。

5.window.name

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"

6.postMessage+iframe

这种?式通常?于获取嵌???中的第三???数据。?个??发送消息,另?个??判
断来源并接收消息
// 发送消息端
<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);
postMessage(data,origin) ?法接受两个参数:
  • data: 要传递的数据, html5 规范中提到该参数可以是 JavaScript 的任意基本类型或可
    复制的对象,然?并不是所有浏览器都做到了这点?,部分浏览器只能处理字符串参
    数,所以我们在传递参数的时候需要使? JSON.stringify() ?法对对象参数序列化
  • origin:字符串参数,指明?标窗?的源,协议 + 主机 + 端?号 [+URL] URL 会被忽
    略,所以可以不写,这个参数是为了安全考虑, postMessage() ?法只会将 message
    传递给指定窗?,当然如果愿意也可以把参数设置为 "*" ,这样可以传递给任意窗?,
    如果要指定和当前窗?同源的话设置为 "/"
文章来源:https://blog.csdn.net/qq_32054169/article/details/135215177
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。