L6zt
  • 993

跨域cors 和 jsnop | koa 提供服务器 (实例前端 -后端演示)

 阅读约 8 分钟

文章目的 验证一下对跨域的理解-

前端需要都需要配置
后端相应配置什么

首先跨域方式不止这两种 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');
});
`

阅读 454发布于 2019-10-26

推荐阅读
目录