同源策略是什么?
链接的组成部分 protocol hostname port pathname search
域名的同源策略就是 协议:protocol 域名:hostname 端口号:port 相同 如果这三个相等就代表着同源
跨域方案有那些?
1.jsonp
2.proxy代理
3.后端设置请求头
4.本地更改host
jsonp
/* 利用浏览器资源访问src
后端一般会给前端暴漏一个参数来命名jsonp的callback函数
前端代码:*/
const script = document.createElement('script');
// 假设一个api
const api = 'https://www.baidu.com?callback=cb';
// 请求的接口链接
script.src = api;
document.body.appendChild(script);
// 回调函数
function cb(res) {
script.remove();
res = res && JSON.parse(res);
console.log(res);
}
// 后端代码已php为例
<?php
$cb = $_GET["callback"];
$obj = array('code' => '0000', 'msg' => '成功', 'data' => array(1,2,3));
echo '$cb + '(' + json_encode($obj) + ')';
?>
proxy
/通过本地假设一个后端服务器 来请求其他后端 因此产生了请求中要带时间数据与上传数据 md5或者sha加密/
假设前端请求时前面可以加一个/api
后端代码已node为例
1.入口
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const { router } = require('./router');
const proxy = require('./proxy');
const util = require('util');
const port = '3322';
let proxyMsg = '';
for (let i = 0; proxy[i]; i++) {
proxyMsg += `路由:${proxy[i].path} 代理到:${proxy[i].url}\n`;
}
proxyMsg += `\n服务器启动成功端口号:${port}`;
http.createServer(async function (req, res) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
let post = '';
let {path, query} = url.parse(req.url, true);
if (req.method === 'OPTIONS') {
return res.end();
}
req.on('data', function(chunk){
post += chunk;
});
req.on('end', function(){
post = querystring.parse(post);
if (req.method === 'POST') {
query = util.inspect(post);
} else {
query = util.inspect(query);
}
let require = router(path, query, req.method, res)
require.then(response => {
res.end(response);
}).catch(err => res.end(err));
});
}, console.log(proxyMsg)).listen(port);
2.路由
const proxy = require('./proxy');
const axios = require('axios');
const qs = require("qs"); //qs是一个url参数转化(parse/stringify)的js库
module.exports = {
router: (path, data, type, res) => {
return new Promise( (resolve, reject) => {
let rep = false;
path = path.substr(1, path.indexOf('?') - 1 != -1 && path.indexOf('?') - 1 || path.length);
firstPath = '/' + path.substr(0, path.indexOf('/') || path.length);
const o = {};
const api = '/' + path.substr(path.indexOf('/'), path.length);
for (let i = 0; proxy[i]; i++) {
if (proxy[i].path === firstPath) {
rep = true;
if (proxy[i].cors === true) {
o.corsUrl = proxy[i].url;
if (type === 'POST') {
return axios.post(proxy[i].url, data).then(res => {
o.code = '0000';
o.data = res.data;
o.msg = '请求成功';
resolve(JSON.stringify(o));
}).catch(err => {
o.code = '0001',
o.errMsg = err,
o.msg = '请求失败';
reject(JSON.stringify(o));
});
} else if (type === 'GET') {
return axios.get(proxy[i].url, {
params: data
}).then(res => {
o.code = '0000';
o.data = res.data;
o.msg = '请求成功';
resolve(JSON.stringify(o));
}).catch(err => {
o.code = '0001',
o.errMsg = err,
o.msg = '请求失败';
reject(JSON.stringify(o));
});
}
}
}
}
resolve(JSON.stringify({
code: 10001,
msg: '请配置代理路由'
}));
} )
}
}
3.proxy配置
module.exports = [
{
path: '/api', // 获取到这个头部就执行跨域
url: 'http://localhost:3911', // 请求链接
cors: true // 跨域
}
]
后端更改请求头 node
Access-Control-Allow-Origin 详解
可以配置 https://www.baidu.com:80?cburl=www.aliyun.com
也可以设置 *://*:*?* 星号代表着全匹配
res.setHeader("Access-Control-Allow-Origin", "*");
更改host
其实就是更改本地映射某个域名为本地项目