vue 项目中如何实现浏览器跨域
在Vue项目中如何实现浏览器跨域?
跨域是指客户端在向服务器请求数据时,请求地址的域名、协议、端口和当前页面地址不匹配,浏览器会提示“跨域错误”(Cross-Origin Resource Sharing)。Vue项目中要实现跨域请求,需要通过一些技术手段来实现。
1. 使用代理
vue-cli3.x版本中已经内置了webpack-dev-server,我们可以在vue.config.js文件中添加proxy配置,对请求进行代理,让不同域名下的请求可以互相访问。具体代码如下:
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': { // 对以 /api 开头的请求进行代理
target: 'http://localhost:3000', // 将所有请求代理到本地的3000端口
ws: true, // 开启 websocket
changeOrigin: true, // 所有请求头的 origin 属性都会被设置为 target
pathRewrite: {
'^/api': '' // 将 /api 前缀替换为空
}
}
}
}
}
然后将请求地址的 /api 替换成我们本地的地址即可:
// 使用 axios 发送请求
axios.get('/api/users')
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.error(err);
});
这样请求就会通过代理服务器,将请求地址替换成本地地址。这种方式无需后端配合,但存在的问题是项目打包后,仍然存在跨域问题。
2. 设置CORS
CORS(Cross-Origin Resource Sharing)是一种跨域传输数据的标准。在服务端返回http响应时,设置响应头,允许指定的域名访问,就可以解决跨域问题了。首先客户端需要发送一次options请求,探测是否允许跨域。options请求只发起一次,响应头中会带有Access-Control-Allow-Headers和Access-Control-Allow-Methods等参数,告诉客户端能够支持的请求方法和头信息类型。
Express中设置CORS的代码如下:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With');
res.header('Access-Control-Allow-Methods','PUT,POST,GET,DELETE,OPTIONS');
if (req.method === 'OPTIONS') {
res.send(200);
} else {
next();
}
});
设置了上述代码后,就可以跨域访问啦!
3. 使用JSONP
JSONP是一种跨域传输数据的方式,通过script标签动态添加到文档中,并指定回调函数,服务器端在获取请求后将数据以callback(jsonData)的形式返回,并由前端设置对应的回调函数即可获取数据。
JSONP的代码如下:
function jsonp(url, params, callback) {
const script = document.createElement('script');
const callbackName = jsonp_${Math.floor(Math.random() * 100000)};
window[callbackName] = (data) => {
delete window[callbackName];
document.body.removeChild(script);
callback(data);
};
const arr = [];
for (let key in params) {
arr.push(${encodeURIComponent(key)}=${encodeURIComponent(params[key])});
}
const query = arr.join('&');
script.src = ${url}?${query}&callback=${callbackName};
document.body.appendChild(script);
}
jsonp('http://localhost:3000/users', {name: '张三'}, (data) => {
console.log(data);
});
JSONP的实现不需要后端配合,缺点是只能使用GET请求,不支持POST等请求方式。
4. 使用postMessage
通过postMessage可以在不同域名下的窗口之间传递数据。在子窗口中发送postMessage,窗口会发送一个带有指定消息的事件。父窗口可以监听message事件,获取到消息的内容。这种方式无需后端配合,但只能在窗口之间进行传递数据。
子窗口的代码如下:
const targetWindow = parent;
targetWindow.postMessage('Hello', 'http://example.com');
父窗口的代码如下:
const origin = 'http://example.com';
window.addEventListener('message', (event) => {
if (event.origin !== origin) return;
console.log(event.data);
});
以上就是在Vue项目中实现跨域的四种方式,我们可以根据项目需要选择相应的方式。
