文章目的 验证一下对跨域的理解 -
前端需要都需要配置
后端相应配置什么
首先跨域方式不止这两种 iframe.posetMessage form 表单也可。
====
项目地址(https://github.com/L6zt/corssDomain-demo)
原理说明:
- jsonp
什么叫做 jsonp 请求,其实就相当于在页面里加载远程脚本资源,
加载完页面就会执行里面的函数,也就是为什么你会发现
jsonp 请求结果里 jsonp1({a: 1}); jsonp1 就是函数(只不过类似 jquery 已经把这个函数 放在 window 下了),
jsonp1({a: 1}) 相当与执行函数,所以你就能拿到数据参数了。
- cors
这个是 xhr 2 提供跨域的方式
cors 文档
我后端 node 服务器,照这个文档写的,纯自手撸。
`const Koa = require(‘koa’);
// 路由
const Router = require(‘koa-router’);
//
const path = require(‘path’);
// 提供静态文件服务
const koaStaticServer = require(‘koa-static-server’);
// 打开浏览器
const opn = require(‘better-opn’);
// 服务器 1
const wwwLocalhostComServer = new Koa();
// 服务器 2
const mLocalhostComServer = new Koa();
// 跨域路由
const wwwCorsRouter = new Router({
prefix: ‘/cors’
});
// 非跨域路由
const wwwNotCorsRouter = new Router({
prefix: ‘/nm’
});
// jsonp 请求
const wwwJsonpRouter = new Router({
prefix: ‘/jsonp’
});
// 跨域接口
wwwCorsRouter.use(‘/’, (ctx, next) => {
const {request} = ctx;
const {header: { origin}, method} = request;
ctx.response.set(‘Access-Control-Allow-Origin’, origin);
next();
}).post(‘/setCookie’, (ctx, next) => {
const result = {
flag: 1,
data: {message: 'we set cookie in different domain',}
};
ctx.response.set(‘Access-Control-Allow-Credentials’, ‘true’);
ctx.response.set(‘Set-Cookie’, auth=love; Expries=${new Date(Date.now() + 60 * 60 * 24 * 10 * 1000)}; Path=/
);
ctx.cookies.set(‘inject’, ‘love’, {
expires: new Date(Date.now() + 60 * 60 * 24 * 10 * 1000),
});
ctx.response.set(‘Content-type’, ‘application/json’);
ctx.body = JSON.stringify(result);
}).post(‘/normalData’, (ctx, next) => {
const result = {
flag: 1,
data: {message: 'we like each other'}
}
ctx.response.set(‘Content-type’, ‘application/json’);
ctx.body = JSON.stringify(result);
});
// 非跨域接口
wwwNotCorsRouter.use(‘/’, (ctx, next) => {
ctx.response.set(‘Custom-Server-Sp’, ‘love’);
next();
}).post(‘/data’, (ctx, next) => {
const result = {
flag: 1,
data: {message: 'we are not in the same domain',}
};
ctx.response.set(‘Content-type’, ‘application/json’);
ctx.body = JSON.stringify(result);
});
// jsonp 接口
wwwJsonpRouter.get(‘/data’, (ctx, next) => {
const {request} = ctx;
const {header: { origin}, method, query} = request;
const {callback} = query;
if (!callback) {
ctx.body = JSON.stringify({
flag: 0,
message: '参数校验失败',
})
return
} else {
// 相当与返回 js 文件
// 文本内容 js 文件
ctx.response.set('Content-type', 'application/javascript');
ctx.body = [`${callback}(`,
JSON.stringify({flag: 0, data: {payload: {key: 'love'}}}),
')'
].join('');
}
})
wwwLocalhostComServer.use((ctx, next) => {
const {request} = ctx;
const {header:{ origin , path}, method} = request;
// 对某些特殊 cors 做处理 详情 mdn 文档
if (method === ‘OPTIONS’) {
ctx.response.set(‘Access-Control-Allow-Origin’, origin);
ctx.response.set(‘Access-Control-Request-Method’ , ‘POST’);
ctx.response.set(‘Access-Control-Allow-Headers’, ‘Content-Type’);
ctx.response.set(‘Access-Control-Allow-Credentials’, true);
ctx.body = ”
} else {
next();
}
});
wwwLocalhostComServer.use(wwwCorsRouter.routes());
wwwLocalhostComServer.use(wwwNotCorsRouter.routes());
wwwLocalhostComServer.use(wwwJsonpRouter.routes());
mLocalhostComServer.use(koaStaticServer({
rootDir: path.join(__dirname, ‘./m.assert’)
}));
wwwLocalhostComServer.use(koaStaticServer({
rootDir: path.join(__dirname, ‘./www.assert’),
}));
wwwLocalhostComServer.listen(7001, () => {
console.log(‘ — *’);
console.log(‘ 端口为 7001 的接口启动了 ’);
console.log(‘ — ‘);
});
mLocalhostComServer.listen(7002, () => {
console.log(‘ — *’);
console.log(‘ 端口为 7002 的服务器启动了 ’);
console.log(‘ — ‘);
opn(‘http://localhost:7002’);
});
`