Web 前端必备的各种跨域方式汇总 All In One
Web 前端必备的各种跨域方式汇总 All In One
跨域方式汇总
同源策略
协议相同 + 域名相同 + 端口相同
https://www.xgqfrms.xyz/index.html
https://www.xgqfrms.xyz:80/index.html
协议是 https://
域名是 www.xgqfrms.xyz
端口是80(默认端口可以省略不写)
demos
https://www.xgqfrms.xyz/blogs/index.html
✅同源(URL path 不同)
http://www.xgqfrms.xyz/blogs/index.html
❌同源(URL protocol 不同)
https://cdn.xgqfrms.xyz/index.html
❌不同源(URL domain 不同)
https://www.xgqfrms.xyz:8090/index.html
❌不同源(URL port 不同)
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
CORS请求
- 简单请求 (simple request)
- 非简单请求 (not-so-simple request)
简单请求
- 请求方法是以下三种方法之一:
HEAD
GET
POST
- HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
是这三个值之一
CORS 预检请求
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests
https://fetch.spec.whatwg.org/#cors-safelisted-request-header
CORS
SRI
CSP
Window.postMessage()
targetWindow.postMessage(message, targetOrigin, [transfer]);
https://caniuse.com/#feat=mdn-api_window_postmessage
https://caniuse.com/#search=postMessage
https://developer.mozilla.org/en-US/docs/Web/API/Client/postMessage
client.postMessage(message[, transfer]);
client.postMessage(message[, { transfer }]);
hash & hashchange
iframe
img
script
JSONP
JSONP 原理
JSONP (JSON with Padding)
-
server using passed callback wrap the JSON data;
-
client using script tag bypassed Cross-Origin limit;
-
after script URL loaded, execute the global callback function
https://cdn.xgqfrms.xyz/jsonp/users.json?callback=jsonpGlobalCallback
// https://cdn.xgqfrms.xyz/jsonp/users.json?callback=jsonpGlobalCallback
jsonpGlobalCallback([
{
"key":1,
"uid": 1024,
"uname":"xgqfrms",
},
{
"key":2,
"uid": 2048,
"uname":"webggeeker",
}
]);
<script src="https://cdn.xgqfrms.xyz/jsonp/users.json?callback=jsonpGlobalCallback"></script>
bug ❌
Fetch API OK ✅
Text !== JSON
/*
err = TypeError: Failed to execute 'json' on 'Response': body stream already read at jsonp.html:40:16
Uncaught (in promise) SyntaxError: Unexpected token 'j', "jsonpGloba"... is not valid JSON
*/
const log = console.log;
const app = document.querySelector(`#app`);
log(`app =`, app);
function jsonpGlobalCallback (arr) {
log(`json =`, arr);
}
const url = `https://cdn.xgqfrms.xyz/jsonp/users.json?callback=jsonpGlobalCallback`;
// const url = `https://cdn.xgqfrms.xyz/jsonp/users.json`;
fetch(url, {
// cors
})
.then(res => {
log(`res =`, res);
// read stream
// log(`res =`, res, res.json());
return res.text();
// return res.json();
})
.then(jsonpText => {
log(`jsonp text =`, jsonpText);
app.innerHTML = ``;
app.insertAdjacentHTML(`beforeend`, jsonpText);
})
.catch(err => {
log(`err =`, err);
});
https://gist.github.com/xgqfrms/801601aec153b5a82364a6b48c0d4403
共享 cookies
规避同源政策
// 设置Cookie的时候,指定Cookie的所属域名为一级域名
Set-Cookie: key=value; domain=.example.com; path=/
WebSocket
Node.js middleware Proxy
中间件代理跨域
Nginx 反向代理
设置 proxy_cookie_domain
Canvas Image
canvas 图片getImageData 跨域???
应用场景
-
第三方接入
-
埋点
-
页面间通信
refs
http://www.ruanyifeng.com/blog/2016/04/cors.html
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
https://juejin.im/post/6844903767226351623
https://juejin.im/post/6856353219036217357
https://segmentfault.com/a/1190000015597029
https://segmentfault.com/a/1190000011145364
https://www.zhangxinxu.com/wordpress/2018/02/crossorigin-canvas-getimagedata-cors/
https://developer.mozilla.org/en-US/docs/Web
©xgqfrms 2012-2020
www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/13424717.html
未经授权禁止转载,违者必究!