“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
定义
只有协议、主机、端口号全都相同的情况下,才能称两个URL同源。
| URL | 同源 | 原因 |
|---|---|---|
| www.baidu.com/test/login.… | ✅ | |
| www.baidu.com/test/test1/… | ✅ | |
| www.baidu.com:81/test/share.… | ❌ | 端口号不同(默认80) |
| www.baidu.com/test/share.… | ❌ | 协议不同 |
| aaa.baidu.com/test/share.… | ❌ | 主机不同 |
目的
保证用户信息安全,防止恶意的对网站进行数据窃取
限制
在非同源的情况下
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM 无法获得
- AJAX 请求不能发送
解决跨域
-
CORS:使用额外的HTTP头来告诉浏览器 让运行在一个 origin 上的 Web 应用被准许访问来自不同源服务器上的指定的资源
-
node
-
原生
app.use(async (ctx, next) => { ctx.set("Access-Control-Allow-Origin", ctx.headers.origin); ctx.set("Access-Control-Allow-Credentials", true); ctx.set("Access-Control-Request-Method", "PUT,POST,GET,DELETE,OPTIONS"); ctx.set( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, cc" ); if (ctx.method === "OPTIONS") { ctx.status = 204; return; } await next(); }); -
第三方
const cors = require("koa-cors"); app.use(cors());
-
-
-
node正向代理:利用服务端请求不会跨域的特性,让接口和当前站点同域。
-
proxy
//webpack const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: { index: "./index.js" }, output: { filename: "bundle.js", path: path.resolve(__dirname, "dist") }, devServer: { port: 8000, proxy: { "/api": { target: "http://localhost:8080" } } }, plugins: [ new HtmlWebpackPlugin({ filename: "index.html", template: "webpack.html" }) ] };//vue2-->config/index.js proxyTable: { '/api': { target: 'http://localhost:8080', } },//vue3-->vue.config.js module.exports = { devServer: { port: 8000, proxy: { "/api": { target: "http://localhost:8080" } } } };
-
-
nginx反向代理:保证当前域能获取到静态资源和接口,但不关心是怎么获取的
//nginx server { listen 80; server_name local.test; location /api { proxy_pass http://localhost:8080; } location / { proxy_pass http://localhost:8000; } } -
JSONP:
script标签没有跨域限制的特性,仅支持get
<script type="text/javascript">
window.jsonpCallback = function(res) {
console.log(res);
};
</script>
<script
src="http://localhost:8080/api/jsonp?msg=hello&cb=jsonpCallback"
type="text/javascript"
></script>
- window.name:无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它;容量大,但影响性能
- window.postMessage:跨文档通信 API,为
window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源