解决 Vue 使用 Axios 进行跨域哀求的方法详解

打印 上一主题 下一主题

主题 919|帖子 919|积分 2757

在开辟当代 Web 应用时,前端和后端通常分离部署在不同的服务器上,这就会引发跨域哀求问题。欣赏器的同源战略(Same-Origin Policy)会阻止跨域哀求,除非后端服务器设置了允许跨域哀求的 CORS(Cross-Origin Resource Sharing)头。本文将具体介绍如安在 Vue 项目中使用 Axios 发起跨域哀求时解决跨域问题。
什么是跨域哀求?

跨域哀求是指欣赏器从一个域向另一个域发送哀求。这种哀求会被欣赏器的同源战略阻止,除非目标域明白允许跨域哀求。常见的跨域哀求包罗:


  • 不同的域名(例如从 example.com 哀求 api.example.com)
  • 不同的端口(例如从 localhost:8080 哀求 localhost:3000)
  • 不同的协议(例如从 http 哀求 https)
解决跨域问题的方法

1. 在后端设置 CORS

解决跨域问题的最佳方法是在后端服务器上设置 CORS 头。下面将介绍如安在常见的后端框架中设置 CORS。
使用 Node.js 和 Express

起首,安装 cors 中心件:
  1. npm install cors
复制代码
然后,在你的 Express 应用中使用它:
  1. const express = require('express');
  2. const cors = require('cors');
  3. const app = express();
  4. const port = 3000;
  5. app.use(cors()); // 允许所有来源的跨域请求
  6. app.post('/login', (req, res) => {
  7.   res.send('登录成功');
  8. });
  9. app.listen(port, () => {
  10.   console.log(`Server is running on http://localhost:${port}`);
  11. });
复制代码
你可以通过传递选项对象来更具体地设置 CORS,例如,只允许特定的域名访问:
  1. app.use(cors({
  2.   origin: 'http://localhost:8080', // 只允许从这个地址的跨域请求
  3.   methods: ['GET', 'POST'], // 允许的 HTTP 方法
  4.   allowedHeaders: ['Content-Type', 'Authorization'] // 允许的请求头
  5. }));
复制代码
使用 Flask

起首,安装 flask-cors:
  1. pip install flask-cors
复制代码
然后,在你的 Flask 应用中使用它:
  1. from flask import Flask, request, jsonify
  2. from flask_cors import CORS
  3. app = Flask(__name__)
  4. CORS(app)  # 允许所有来源的跨域请求
  5. @app.route('/login', methods=['POST'])
  6. def login():
  7.     return jsonify({'message': '登录成功'})
  8. if __name__ == '__main__':
  9.     app.run(port=3000)
复制代码
你也可以指定允许的来源:
  1. CORS(app, resources={r"/api/*": {"origins": "http://localhost:8080"}})
复制代码
2. 在开辟环境中使用代理

在开辟环境中,使用 Webpack 开辟服务器的代理功能可以解决跨域问题。Vue CLI 提供了简朴的设置方式来设置代理。
在 vue.config.js 中添加以下设置:
  1. module.exports = {
  2.   devServer: {
  3.     proxy: {
  4.       '/api': {
  5.         target: 'http://localhost:3000',
  6.         changeOrigin: true,
  7.         pathRewrite: { '^/api': '' }
  8.       }
  9.     }
  10.   }
  11. }
复制代码
在你的前端代码中,将哀求路径修改为以 /api 开头:
  1. this.$axios.post('/api/login', {
  2.   username: this.username,
  3.   password: this.password
  4. })
  5. .then(response => {
  6.   console.log(response.data);
  7. })
  8. .catch(error => {
  9.   console.error(error);
  10. });
复制代码
如许,所有发往 /api 的哀求都会被代理到 http://localhost:3000。
3. 使用 Nginx 反向代理

Nginx 可以设置反向代理,将前端的哀求转发到后端服务器,避免跨域问题。起首,确保你的 Nginx 已经安装并运行。
在你的 Nginx 设置文件(通常在 /etc/nginx/nginx.conf 或 /etc/nginx/sites-available/default)中添加反向代理设置:
  1. server {
  2.     listen 80;
  3.     server_name yourdomain.com;
  4.     location / {
  5.         root /var/www/html;
  6.         index index.html;
  7.         try_files $uri $uri/ /index.html;
  8.     }
  9.     location /api/ {
  10.         proxy_pass http://localhost:3000/;  # 将 /api 前缀的请求转发到后端服务器
  11.         proxy_http_version 1.1;
  12.         proxy_set_header Upgrade $http_upgrade;
  13.         proxy_set_header Connection 'upgrade';
  14.         proxy_set_header Host $host;
  15.         proxy_cache_bypass $http_upgrade;
  16.     }
  17. }
复制代码
然后重启 Nginx:
  1. sudo systemctl restart nginx
复制代码
4. 使用 iframe + postMessage

这种方法适用于需要从前端应用向不同源进行通信的情况。通过在前端页面中嵌入 iframe 并使用 postMessage API 进行通信,可以绕过同源战略。
  1. <!-- index.html -->
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5.     <meta charset="UTF-8">
  6.     <title>Iframe PostMessage Example</title>
  7. </head>
  8. <body>
  9.     <iframe id="myIframe" src="http://different-origin.com/iframe.html" style="display:none;"></iframe>
  10.     <script>
  11.         const iframe = document.getElementById('myIframe');
  12.         window.addEventListener('message', (event) => {
  13.             if (event.origin === 'http://different-origin.com') {
  14.                 console.log('Received:', event.data);
  15.             }
  16.         });
  17.         iframe.onload = () => {
  18.             iframe.contentWindow.postMessage('Hello from parent', 'http://different-origin.com');
  19.         };
  20.     </script>
  21. </body>
  22. </html>
复制代码
5. 使用服务器代理中心件

在 Node.js 环境下,你可以使用中心件来代理哀求。例如,在 Express 应用中使用 http-proxy-middleware:
起首,安装中心件:
  1. npm install http-proxy-middleware
复制代码
然后,在你的 Express 应用中设置代理:
  1. const express = require('express');
  2. const { createProxyMiddleware } = require('http-proxy-middleware');
  3. const app = express();
  4. app.use('/api', createProxyMiddleware({
  5.     target: 'http://localhost:3000',
  6.     changeOrigin: true
  7. }));
  8. app.listen(8080, () => {
  9.     console.log('Server is running on http://localhost:8080');
  10. });
复制代码
6. 使用 GraphQL 服务

GraphQL 允许客户端机动地查询和操纵数据。通过将前端哀求统一发送到 GraphQL 服务,并在该服务中处理不同源的哀求,可以避免直接跨域哀求的问题。
7. 设置欣赏器忽略 CORS(开辟环境)

在开辟环境中,可以通过设置欣赏器忽略 CORS 验证。这种方法仅用于开辟调试,不保举在生产环境中使用。
例如,在 Chrome 中,可以使用以下下令启动欣赏器忽略 CORS 验证:
  1. chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
复制代码
8. 服务器端渲染 (SSR)

使用服务器端渲染(例如使用 Nuxt.js 进行 Vue 项目标 SSR),可以在服务器上进行所有的 API 哀求,避免欣赏器的 CORS 限制。
9. CORS 预检哀求(OPTIONS 哀求)

确保后端正确处理预检哀求(OPTIONS 哀求)。当使用复杂哀求(例如带有自定义头部的哀求)时,欣赏器会发送一个 OPTIONS 哀求来检查服务器是否允许该实际哀求。
示例:使用 Express 处理预检哀求:
  1. app.options('/api/*', (req, res) => {
  2.     res.header('Access-Control-Allow-Origin', '*');
  3.     res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  4.     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  5.     res.send();
  6. });
复制代码
处理 Axios 的跨域哀求错误

检查 Axios 设置

确保 Axios 设置正确,例如设置 baseURL 和处理错误相应:
  1. import axios from 'axios';
  2. const instance = axios.create({
  3.   baseURL: 'http://localhost:3000', // 设置后端 API 的基本 URL
  4.   timeout: 10000, // 设置请求超时时间
  5. });
  6. instance.interceptors.response.use(
  7.   response => response,
  8.   error => {
  9.     console.error('API error:', error);
  10.     return Promise.reject(error);
  11.   }
  12. );
  13. export default instance;
复制代码
在 Vue 组件中使用 Axios

在 Vue 组件中使用设置好的 Axios 实例:
  1. <template>
  2.   <div>
  3.     <h1>{{ message }}</h1>
  4.   </div>
  5. </template>
  6. <script>
  7. import axios from './http'; // 导入配置好的 Axios 实例
  8. export default {
  9.   data() {
  10.     return {
  11.       message: ''
  12.     };
  13.   },
  14.   mounted() {
  15.     axios.post('/login', {
  16.       username: 'test',
  17.       password: 'test'
  18.     })
  19.     .then(response => {
  20.       this.message = response.data;
  21.     })
  22.     .catch(error => {
  23.       console.error('HTTP error:', error);
  24.     });
  25.   }
  26. };
  27. </script>
复制代码
总结

跨域哀求问题是前后端分离开辟中常见的问题,可以通过在后端设置 CORS、在开辟环境中使用代理以及其他方法来解决。最优的解决方案是设置后端服务器以允许必要的跨域哀求,从而保证应用的安全性和稳固性。希望本文能资助你全面了解息争决 Vue 项目中使用 Axios 发起跨域哀求时碰到的问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表