跨域cors 和 jsnop | koa 提供服务器 (实例前端 -后端演示)
文章目的 验证一下对跨域的理解-
前端需要都需要配置
后端相应配置什么
首先跨域方式不止这两种 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');
});
`