Vue项目中的AJAX请求与跨域问题解析

一、AJAX请求方式对比与选型

1. 原生XHR方式

基本使用示例:

缺点分析:

  • 代码冗长复杂

  • 回调地狱问题

  • 需要手动处理JSON转换

  • 错误处理不够直观

2. jQuery的AJAX

基本使用示例:

复制代码
$.ajax({
  url: 'http://localhost:5000/api/data',
  type: 'GET',
  success: function(data) {
    console.log(data)
  },
  error: function(err) {
    console.error(err)
  }
})

优缺点分析:

  • 优点:

    • 简化了原生XHR的使用

    • 解决了浏览器兼容性问题

    • 提供了丰富的配置选项

  • 缺点:

    • 引入了整个jQuery库,体积较大

    • 不符合现代前端开发趋势(Vue/React不推荐操作DOM)

    • 回调方式不如Promise直观

3. Fetch API

基本使用示例:

复制代码
fetch('http://localhost:5000/api/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok')
    }
    return response.json()
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error))

优缺点分析:

  • 优点:

    • 浏览器原生支持,无需额外库

    • 基于Promise的现代API

    • 更简洁的语法

  • 缺点:

    • IE浏览器完全不支持

    • 需要手动处理JSON转换

    • 错误处理不够直观(不会reject HTTP错误状态)

    • 功能相对简单,缺少拦截器等高级功能

4. Axios

基本使用示例:

复制代码
axios.get('http://localhost:5000/api/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error))

优势分析:

  1. Promise风格:解决了回调地狱问题

  2. 浏览器/Node.js通用:同构API设计

  3. 丰富的功能:

    • 拦截请求和响应

    • 转换请求和响应数据

    • 自动JSON数据转换

    • 客户端支持防御XSRF

  4. 更好的错误处理:会reject HTTP错误状态

  5. 活跃的社区支持:持续维护更新

选型结论:在Vue项目中推荐使用Axios作为HTTP客户端

二、Axios的安装与使用详解

1. 安装Axios

复制代码
npm install axios
# 或
yarn add axios

2. 基本使用方式

2.1 发起GET请求
复制代码
import axios from 'axios'

// 方式一:直接使用axios对象
axios.get('/user?ID=12345')
  .then(response => console.log(response.data))
  .catch(error => console.error(error))

// 方式二:使用config对象
axios({
  method: 'get',
  url: '/user',
  params: {
    ID: 12345
  }
})
.then(response => console.log(response.data))
2.2 发起POST请求
复制代码
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(response => console.log(response.data))
2.3 并发请求
复制代码
const getUser = axios.get('/user/12345')
const getPermissions = axios.get('/user/12345/permissions')

axios.all([getUser, getPermissions])
  .then(axios.spread((userResp, permResp) => {
    console.log(userResp.data, permResp.data)
  }))

3. 高级配置

3.1 创建实例
复制代码
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
})
3.2 请求拦截器
复制代码
axios.interceptors.request.use(config => {
  // 在发送请求前添加token
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})
3.3 响应拦截器
复制代码
axios.interceptors.response.use(
  response => response.data, // 直接返回data字段
  error => {
    if (error.response.status === 401) {
      // 处理未授权错误
      router.push('/login')
    }
    return Promise.reject(error)
  }
)

三、跨域问题解析

1. 跨域现象与原理

同源策略限制的三要素:

  1. 协议相同(http/https)

  2. 主机名相同(localhost/example.com)

  3. 端口号相同(8080/5000)

跨域错误提示:

复制代码
Access to XMLHttpRequest at 'http://localhost:5000/api' from origin 'http://localhost:8080' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

实际请求过程:

  1. 浏览器发送实际请求前会先发送OPTIONS预检请求

  2. 服务端需要响应预检请求,声明允许的跨域策略

  3. 只有预检通过后,浏览器才会发送真正的请求

2. 跨域解决方案对比

方案 实现方式 优点 缺点 适用场景
CORS 服务端设置响应头 官方标准,前端无需额外处理 需要服务端支持 生产环境,可控的服务端
JSONP 动态创建script标签 兼容老浏览器 仅支持GET,安全性低 需要支持老系统的场景
代理服务器 前端服务转发请求 前端无需修改,开发环境友好 生产环境需要Nginx配置 开发环境,前后端分离项目

四、Vue代理方案详解

1. 代理原理说明

复制代码
浏览器 (http://localhost:8080)
  → Vue开发服务器 (http://localhost:8080)
    → 实际API服务器 (http://localhost:5000)

代理服务器充当中间人角色,利用服务端请求不受同源策略限制的特性解决跨域问题。

2. 配置方法

2.1 简单配置(方案一)

vue.config.js:

复制代码
module.exports = {
  devServer: {
    proxy: 'http://localhost:5000'
  }
}

特点:

  • 所有请求都会被代理到目标服务器

  • 无法配置多个后端服务

  • 会优先匹配本地存在的文件

2.2 高级配置(方案二)

vue.config.js:

复制代码
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:5000', // 目标服务器
        pathRewrite: {'^/api': ''},     // 重写路径
        changeOrigin: true,             // 修改请求头中的host
        ws: true                        // 支持websocket
      },
      '/api2': {
        target: 'http://localhost:5001',
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}

配置项说明:

  • target:代理目标地址

  • pathRewrite:路径重写规则

  • changeOrigin:修改请求头中的host值(true时,host会被设置为target)

  • ws:是否代理websocket连接

3. 前端请求示例

复制代码
// 请求会被代理到 http://localhost:5000/user
axios.get('/api/user')
  .then(response => console.log(response.data))

// 另一个服务的请求会被代理到 http://localhost:5001/order
axios.get('/api2/order')
  .then(response => console.log(response.data))

4. 生产环境部署

开发环境使用Vue代理,生产环境推荐使用Nginx反向代理:

复制代码
server {
  listen 80;
  server_name example.com;
  
  location /api {
    proxy_pass http://localhost:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
  
  location / {
    root /path/to/dist;
    try_files $uri $uri/ /index.html;
  }
}

五、最佳实践建议

  1. 开发环境:

    • 使用Vue代理方案二

    • 为不同后端服务配置不同前缀

    • 启用changeOrigin避免某些服务器的host校验

  2. 生产环境:

    • 使用Nginx反向代理

    • 配置合适的CORS策略(如需)

    • 启用HTTPS加密通信

  3. Axios使用:

    • 封装统一的请求实例

    • 添加拦截器处理通用逻辑

    • 对API进行模块化管理

    • 统一错误处理机制

  4. 安全考虑:

    • 生产环境限制CORS来源

    • 敏感接口添加身份验证

    • 对代理转发的请求进行适当过滤

相关推荐
兰亭妙微UI设计公司3 小时前
兰亭妙微软件界面设计公司的解锁按钮设计10大密码
开发语言·前端·javascript
迪幻4 小时前
封装自己的 npm 依赖并存储到个人 GitHub
前端·npm·github
u0111026754 小时前
WebP 转成 PNG 后为什么更大?图片格式转换不等于压缩
前端·javascript·vue.js
万少4 小时前
Qoder sonus模型 20分钟,复刻 马斯克 飞天汽车
前端·后端·算法
seconp4 小时前
基于Spring Boot和Vue 3的智慧旅游网站:住宿预订、行程规划与千问接入
vue.js·spring boot·毕业设计·软件工程·课程设计·旅游·毕设
java1234_小锋4 小时前
【技术专题】HTML5 网页技术 - HTML5 列表标签
前端·html·html5
强二小哥帅4 小时前
Kotlin 协程复习笔记
前端
不可能片场4 小时前
工程实践 原子替换改了 ctime 怎么修
前端·electron
暧暧内含光4 小时前
HTTP 文件传输体系全解:从协议标头、OSS 架构到流媒体分片
前端
静默回滚4 小时前
浏览器能显示AVIF,却导不出一张AVIF
前端