Open AlexZ33 opened 4 years ago
关闭浏览器跨域限制 (不推荐,会有安全问题)
open -a /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域(http-proxy-middleware)
9、 WebSocket协议跨域
需要后端单独支持,已经不推荐使用了
// JSONP
function createJsonp() {
var script = document.createElement("script"),
timeName = new Date().getTime() + Math.round(Math.random() * 1000),
callback = "JSONP_" + timeName;
window[callback] = function(data) {
clearTimeout(timeout_flag);
document.body.removeChild(script);
success(data);
}
script.src = url + (url.indexOf("?") > -1 ? "&" : "?") + "callback=" + callback;
script.type = "text/javascript";
document.body.appendChild(script);
setTime(callback, script);
}
//设置请求超时
function setTime(callback, script) {
if (timeOut !== undefined) {
timeout_flag = setTimeout(function() {
if (dataType === "jsonp") {
delete window[callback];
document.body.removeChild(script);
} else {
timeout_bool = true;
xhr && xhr.abort();
}
console.log("timeout");
}, timeOut);
}
}
react
1):安装http-proxy-middleware管理包,cnpm http-proxy-middleware --save
const proxy = require(‘http-proxy-middleware‘);
module.exports = function(app) {
app.use(proxy(‘/api‘, {
target: ‘http://192.168.1.144:8181‘ ,
secure: false,
changeOrigin: true,
pathRewrite: {
"^/api": "/"
},
// cookieDomainRewrite: "http://localhost:3000"
}));
};
vue.config.js
devServer: {
host: '0.0.0.0',
port: 8081,
https: false,
hotOnly: false,
disableHostCheck: true,
// proxy: {
// '/api': {
// target: 'https://m.youpin.mi.com',
// ws: true,
// changeOrigin: true,
// pathRewrite: {
// '^/api': '/api', // rewrite path
// },
// headers: {
// Origin: 'https://m.youpin.mi.com',
// Referer: 'https://m.youpin.mi.com',
// Cookie: 'beegosessionID=94c74e9ad23'
// }
// },
}
终极解决方案,
server {
listen 8092;
server_name aa.app.xiaomiyoupin.com;
error_log /usr/local/etc/nginx/logs/shop.error.log;
access_log /usr/local/etc/nginx/logs/shop.access.log;
# 前端页面走本地(vue-cli开的server)
location / {
proxy_pass http://localhost:8081;
}
# 后端接口都是/api开头的
location /api {
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-NginX-Proxy true;
# proxy_set_header Connection "";
proxy_set_header Host app.xiaomiyoupin.com;
# proxy_pass http://st.shop.youpin.srv;
proxy_pass https://m.xiaomiyoupin.com;
}
location ~ ^/app/shopv3/ {
proxy_set_header Cookie 'beegosessionID=94c74e9ad2349278b5a67fa17076230e; b_auth=mijiayoupin; serviceToken=cTww0DUseqPODIcT5cvyy9nNT+yBPhcaVfZcWmmlV5N6ajVrta+HoJPzdbhB08jVYVbFX5bNseY2MJitcQED7x1k3CoCAApFfaXeCC7n45Iqn7OSkvIr7spQqX4QGIQXGxwg9Ddn8zW/w4Wjc4qssQ==; cUserId=DKtjN6Lk5SugGBs04CbYODo2nsI; YPToken=4PberWbMNP6-TSzQkMdASH5N5PVDEObS0YFnL-h91PwlqjBU7QO5k5wZ7AKfUE3h';
proxy_set_header Referer 'https://m.xiaomiyoupin.com';
# proxy_set_header Host $host;
proxy_pass https://m.xiaomiyoupin.com;
}
}
每次都发送两次请求,并发量比较大的时候,对服务器压力比较大
app.use('*',function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*'); //这个表示任意域名都可以访问,这样写不能携带cookie了。
// res.header('Access-Control-Allow-Origin', 'http://www.baidu.com'); //这样写,只有www.baidu.com 可以访问。
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//设置方法
if (req.method == 'OPTIONS') {
res.send(200); // 意思是,在正常的请求之前,会发送一个验证,是否可以请求。
}
else {
next();
}
});
完整的server例子
var express = require('express')
var app = express()
// var cors = require('cors')
// app.use(cors())
// var corsOptions = {
// origin: 'http://www.baidu.com', //只有百度可以访问
// optionsSuccessStatus: 200
// }
// app.get('/products/:id', cors(corsOptions), function (req, res, next) {
// res.json({msg: '只有百度可以访问'})
// })
app.use('*',function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*'); //这个表示任意域名都可以访问,这样写不能携带cookie了。
// res.header('Access-Control-Allow-Origin', 'http://www.baidu.com'); //这样写,只有www.baidu.com 可以访问。
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//设置方法
if (req.method == 'OPTIONS') {
res.send(200); // 意思是,在正常的请求之前,会发送一个验证,是否可以请求。
}
else {
next();
}
});
app.get('/',function(req,res){
res.send('hello')
})
app.post('/api2',function(req,res){
// console.log(req)
res.json({
"data":1
})
// res.send({some:'json'});
})
app.get('/api3',function(req,res){
// console.log(req)
res.jsonp({
"data":1
})
// res.send({some:'json'});
})
app.listen(3000, function () {
console.log('CORS-enabled web server listening on port 3000')
})
cors
线上: Node.js如何设置允许跨域
开发环境:
nignx:
JSONP
有时我们需要给非本域的页面提供接口服务,又由于一些历史原因无法通过 CORS 实现,可以通过 JSONP 来进行响应。