本文主要讲解一些跨域的处理,附有部分源码。
JSONP跨域原理
**JSONP **是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback 或者开始就定义一个回调方法,参数给服务端,然后服务端返回数据时会将这个callback 参数作为函数名来包裹住 JSON 数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
当GET请求从后台页面返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用后台页面中的一个callback函数。
利用了
<script>
function callback(data){
console.log(data);
}
</script>
<script src="http://localhost:2020/friends?callback=callback"></script>
(2)使用ajax实现jsonp跨域:
<script>
$.ajax({
url:'http://localhost:2020/friends?callback=callback',
method:'get',
dataType:'jsonp', //=> 执行jsonp请求
success:(res) => {
console.log(res);
}
})
function callback(data){
console.log(data);
}
</script>
服务端代码:
router.get('/friends', (req, res) => {
let { callback } = req.query;
let data = [
{name:"tom"},
{name:"jerry"}
]
res.send(`${callback}(${JSON.stringify(data})`)
})
这个主要在服务端使用node的时候进行配置。
通过设置响应头配置了CORS跨域。主要设置以下几个属性。
app.all("*",function(req,res,next){
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin","*");
//允许的header类型
res.header("Access-Control-Allow-Headers","content-type");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
if (req.method.toLowerCase() == 'options')
res.send(200); //让options尝试请求快速结束
else
next();
});
devServer: {
proxy:{
'/api':{
target:'http://localhost:3000', //请求域名
changeOrigin: true, //是否跨域
pathRewrite:{'/api':''}
}
}
},
解释:服务端接口: http://localhost:8080/api/user
客户端项目跑在:http://localhost:3000 下
这个时候想要请求接口就会存在跨域问题,需要修改webpack中的devServer配置
使用proxy代理,在处理接口为"/api"时,将target设置为后端接口的地址。
如上代码是为了解决:当后端端口为
(1)http://localhost:3000/user
(2)http://localhost:3000/admin
(3)http://localhost:3000/vipUser
这个时候,要使用webpack配置跨域的话devServer中的proxy要检测每个接口的名字修改target,
所以我们可以在前端一律将请求地址修改为
(1)http://localhost:3000/api/user
(2)http://localhost:3000/api/admin
(3)http://localhost:3000/api/vipUser
接下来,我们只需要在proxy中匹配’/api’,最后使用pathRewrite将/api替换为空即可。
这个时候我们手里只有html、css、js等静态文件,后台接口地址都会访问不到。这个时候Nginx就登场了,Nginx反向代理配置和Webpack大同小异,匹配到动态的地址时将请求转发到一个服务器地址实现跨域。
server {
listen 3000; //监听的本地端口
server_name localhost;
location /api { //匹配到/api开头的接口时,转发到下面的服务器地址
root html;
proxy_pass http://192.168.xxx.xxx:8080; //服务器地址
}
location =/ {
root html;
index index.htm index.html; //默认主页
}
# 所有静态请求都由nginx处理,存放目录为html
location ~ \.(htm|html|js|css|jpg|png|gif|eot|svg|ttf|woff|woff2)$ {
root html; //配置静态资源地址
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
which person i love is not my lover!