什么是跨域
- 客户端地址与数据服务器地址,只要协议、域名、端口号中的一个不一样,那就是跨域
- 跨域是浏览器的安全机制引起的
JSONP
利用<script> (或者<link>、<img>)等不存在跨域限制的标签
缺点:只支持get请求
-
过程:
在客户端定义好全局函数fn后,通过script标签 -> <script scr='http://127.0.0.1:8888/user/list?callback=fn'> 发送请求,即把fn当做参数发送给服务器
服务器端接受到这个请求,同时也可以获取callback传递的值(这个callback名字要前后台一起协商),即fn,服务器端把参数准备好,返回给客户端 - > "fn([...params] b )"
客户端获取到fn([...params]),即让浏览器把fn执行,然后把...params当做参数传递给fn
百度的搜索就是通过JSONP来做的
CROS
- 服务器允许当前客户端发请求
- CROS并不需要前端做什么特别的操作
- ALLOW_ORIGIN 的设置只允许单一源或者* ,因此 , 我们可以通过设置白名单来指定域名地址,动态获取地址后与白名单比较再添加到ALLOW_ORIGIN中
- 下面是node(express)中如何设置CROS
module.exports = {
//=>WEB服务端口号
PORT: 3001,
//=>CROS跨域相关信息
CROS: {
ALLOW_ORIGIN: 'http://127.0.0.1:5500',
// * 允许所有源 但是不允许携带资源凭证
ALLOW_METHODS: 'PUT,POST,GET,DELETE,OPTIONS,HEAD',
HEADERS: 'Content-Type,Content-Length,Authorization, Accept,X-Requested-With',
CREDENTIALS: true
}
};
app.use((req, res, next) => {
const {
ALLOW_ORIGIN,
CREDENTIALS,
HEADERS,
ALLOW_METHODS
} = CONFIG.CROS;
res.header("Access-Control-Allow-Origin", ALLOW_ORIGIN);
res.header("Access-Control-Allow-Credentials", CREDENTIALS);
res.header("Access-Control-Allow-Headers", HEADERS);
res.header("Access-Control-Allow-Methods", ALLOW_METHODS);
req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS!') : next();
});
proxy
- proxy的原理即弄一个代理服务器:
- 后台和后台之间,除非设置了黑名单,否则是不存在跨域一说的,跨域是浏览器(即客户端)的安全性引起的
- 因此 ,只要保证我们自己起的代理服务器和客户端同源即可,请求数据可通过代理服务器去做
我们前端可以通过webpack的dev-server插件创建代理服务
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/main.js',
output: {
filename: 'main.[hash].min.js',
path: path.resolve(__dirname, 'build')
},
devServer: {
port: '3000',
compress: true,
open: true,
hot: true,
proxy: {
'/': {
target: 'http://127.0.0.1:3001',
changeOrigin: true
}
}
},
// 配置WEBPACK的插件
plugins: [
new HtmlWebpackPlugin({
template: `./public/index.html`,
filename: `index.html`
})
]
};
Vue-cli中已经帮助我们配置好webpack了,我们只需要建立一个vue.config.js文件写以下代码即可
module.exports = {
devServer: {
proxy: "https://..."
}
};
服务器真实上线的时候,可以通过nginx设置反向代理
- 因此我们可以本地开发的时候 在vue/react中可以通过dev-server实现跨域代理,部署上线的时候,通过nginx做代理