欢迎访问宙启技术站
智能推送

vue 项目中如何实现浏览器跨域

发布时间:2023-05-18 02:05:11

在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项目中实现跨域的四种方式,我们可以根据项目需要选择相应的方式。