跨域--jsonp、webpack、koa2-cors解决跨域
书接上一章:跨域--通过代码一步一步了解其本质 。上一章我们简单在本地搭建了前后端分离项目,从代码的层面的理解跨域。这一章是我们的实践篇,完整代码在我的git上,阅读readme获取正确姿势。本章内容如下:
- jsonp原理分析
- koa项目引入koa-cors解决跨域问题
- webpack项目开发时候解决问题
jsonp
jsonp主要目的是让网页从其他域名获取数据,就是跨域资源获取。其主要是利用script不适用同源策略,通过src能够请求其他域名的数据。
代码实现
客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
function callback(result) {
console.log(result)
}
</script>
<script type="text/javascript" src="http://127.0.0.1:3000/jsonp?callback=callback">
</script>
</body>
</html>
服务端代码
router.get('/jsonp', async (ctx) => {
// 获取回调函数名字
let callbackName = ctx.query.callback || 'callback'
// 返回数据定义
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime(),
}
}
// 返回js代码(即:执行回到函数)
let jsonpStr = `${callbackName}(${JSON.stringify(returnData)})`
// 设置Content-Type
ctx.type = 'text/javascript'
ctx.body = jsonpStr
})
原理分析
- 客户端第一个script定义回调函数
- 第二个script发送请求,带上回调函数名字
- 服务端拼装执行回调的js代码
- 客户端获取到后台的js代码并执行
- 获取到数据
ps:jsonp只使用与get请求
koa-cors
通常跨域是由后端处理。每种语言都要相应的第三方包,进行处理。对于koa2项目引入koa2-cors即可解决问题
// 解决跨域问题
app.use(cors({
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
maxAge: 5,
// 允许接收cookie
credentials: true,
allowMethods: ['GET', 'POST', 'DELETE', 'PUT'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))
webpack-dev proxy 配置解决跨域
此种方式只使用与开发模式,在webpack.config.js或者vue-config.js中配置如下
devServer: {
// 启用热更新
hot: true,
port: 3000,
contentBase: path.resolve(__dirname, '../dist'),
compress: true,
// 代理配置
proxy: {
'/api': {
target: 'http://10.10.0.135:8899',
changeOrigin : true, // 域名
secure: false, // 是否支持https
pathRewrite: {'^/api': ''} // 重写url
},
}
}
注意理解路径重写(pathRewrite)
-
以上诉代码为例。在没有路径重写的情况之下:/api/xx 代理为 http://127.0.0.1:3000/api/xx
-
在有路径重写的情况下:/api/xx 代理为 http://127.0.0.1:3000/xx