当前位置: 首页 > article >正文

请求接口时跨域问题详细解决方案

浏览器中的报错:
在这里插入图片描述
跨域问题通常需要前端和后端协作解决。以下是一些常用的解决方法,分别从前端和后端的角度进行讲解:

一. 后端解决方案

  1. 设置 CORS 头部
    最常用和推荐的方法是后端服务器设置 Access-Control-Allow-Origin 响应头来允许特定的前端域名访问资源。

    Access-Control-Allow-Origin: https://your-frontend-domain.com
    

    如果需要支持所有域,可以设置为 *,但出于安全考虑,最好指定具体的域名。

  2. Preflight 请求处理
    对于除 GETPOSTHEAD 之外的非简单请求,浏览器会先发送一个 OPTIONS 请求来询问服务器是否允许跨域请求。后端需要正确响应这个预检请求,并设置相应的 Access-Control-Allow-MethodsAccess-Control-Allow-Headers 头部。

    Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    Access-Control-Allow-Headers: Content-Type, Authorization
    
  3. Cookie 支持
    如果需要在跨域请求中携带 Cookie(例如,用于用户身份验证),后端需要设置 Access-Control-Allow-Credentialstrue,并且不能将 Access-Control-Allow-Origin 设置为 *

    Access-Control-Allow-Credentials: true
    

二. 前端解决方案

1.使用代理服务器

使用代理服务器解决跨域问题是一种常见的做法,尤其是在开发环境中。这种方法的核心思想是将前端应用的跨域请求转发到代理服务器,然后由代理服务器将请求转发到目标服务器,并将响应返回给前端。这样,从浏览器的角度看,所有的请求都是发送给了同源的代理服务器,从而避免了跨域问题。

以下是使用代理服务器解决跨域问题的步骤:

1.1 设置代理服务器

在前端项目中,你可以使用各种工具和框架来设置代理服务器。以下是一些常见的方法:

1.1.1 使用 Vue CLI

如果你的项目是基于 Vue.js 并且使用了 Vue CLI,你可以在项目的 vue.config.js 文件中配置代理:

module.exports = {
  devServer: {
    proxy: {
      '/api': { // 匹配所有到 /api 的请求
        target: 'http://aider.meizu.com', // 目标服务器的地址
        changeOrigin: true, // 是否改变请求头中的Origin字段
        pathRewrite: {
          '^/api': '' // 重写请求路径,去掉路径中的 /api
        }
      }
    }
  }
};

本人在项目中的使用案例代码:
我项目中的接口:
http://aider.meizu.com/app/weather/listWeather?cityIds=101240101
在这里插入图片描述
组件中使用:
在这里插入图片描述

1.1.2 使用 Create React App

如果你的项目是基于 React.js 并且使用了 Create React App,你可以在 package.json 文件中添加代理配置:

{
  "proxy": "http://aider.meizu.com"
}

这会自动将所有非静态资源请求代理到指定的服务器。

1.1.3 使用 Webpack Dev Server

如果你使用的是 Webpack Dev Server,可以在 webpack.config.jswebpack.dev.js 中配置代理:

module.exports = {
  // ...
  devServer: {
    proxy: {
      '/api': { // 匹配所有到 /api 的请求
        target: 'http://aider.meizu.com', // 目标服务器的地址
        changeOrigin: true,
        pathRewrite: {
          '^/api': '' // 重写请求路径,去掉路径中的 /api
        }
      }
    }
  }
};
1.2 发送请求

配置好代理后,你可以在前端代码中发送请求,就像请求是同源的一样。例如,如果你配置了 /api 路径的代理,你可以这样发送请求:

axios.get('/api/app/weather/listWeather?cityIds=101240101')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error fetching weather data:', error);
  });
1.3注意事项
  • 安全性:在生产环境中使用代理时,需要确保代理服务器的安全性,避免潜在的安全风险。
  • 性能:代理服务器可能会引入额外的网络延迟,尤其是在代理服务器与目标服务器之间的网络延迟较大时。
  • 维护性:使用代理服务器可能会增加系统的复杂性,需要额外的维护工作。

使用代理服务器解决跨域问题是开发中常用的方法,特别是在开发阶段,它可以有效地避免跨域问题,使得前端开发更加顺畅。

2. JSONP

对于只支持 GET 请求的跨域数据获取,可以使用 JSONP。但这种方法逐渐被更现代的 CORS 替代,因为它只支持 GET 请求,并且不如 CORS 安全。

function jsonp(url, callback) {
  const script = document.createElement('script');
  script.src = `${url}?callback=${callback}`;
  document.head.appendChild(script);
}
3.PostMessage

对于需要从不同源接收数据的场景,可以使用 window.postMessage 方法。这种方法适用于像 iframe 这样的场景,其中两个窗口需要安全地传递消息。

// 发送消息
window.parent.postMessage('Hello there!', '*');

// 接收消息
window.addEventListener('message', (event) => {
  console.log('Received message:', event.data);
});
4. 使用第三方服务

对于不想或不能修改后端代码的情况,可以使用第三方 CORS 代理服务,如 CORS Anywhere。这些服务作为一个中间人,将请求转发到目标服务器并返回响应。

// 通过第三方服务代理请求
fetch('https://cors-anywhere.herokuapp.com/http://example.com/api/data');

三. 综合考虑

  • 安全性:在后端设置 CORS 是最安全的方法,因为它允许服务器精确控制哪些源可以访问资源。
  • 灵活性:使用代理服务器在开发环境中提供了灵活性,但可能不适合生产环境。
  • 兼容性:JSONP 和 PostMessage 提供了兼容性解决方案,但有其局限性。

在实际应用中,推荐优先考虑后端设置 CORS,因为它提供了最好的安全性和控制。对于开发环境,代理服务器是一个实用的解决方案。


http://www.kler.cn/a/391000.html

相关文章:

  • SpringBoot(八)使用AES库对字符串进行加密解密
  • Node.Js+Knex+MySQL增删改查的简单示例(Typescript)
  • Qt 编写插件plugin,支持接口定义信号
  • 智能零售柜商品识别
  • PHP爬虫快速获取京东商品详情(代码示例)
  • html+js+css实现拖拽式便签留言
  • 前端开发调试之 PC 端调试
  • 使用 `RestTemplate` 获取二进制数据并返回 `byte[]`:解决方案与示例
  • Java 多态 (Polymorphism)详解
  • 智能社区服务小程序+ssm
  • MySQL数据库:SQL语言入门 (学习笔记)
  • ubuntu 20.04添加ros官方的软件源(解决下载ros软件包出现的E 无法定位软件包的问题)
  • ERP学习笔记-预处理eeglab
  • Transformer模型中的位置编码介绍
  • 群晖 Docker 容器文件夹出现未知用户 UID 1000
  • 开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频
  • 云计算在教育领域的应用
  • 数据库基础(10) . MySQL函数
  • 【MATLAB源码-第291期】基于matlab的AMI编码解码系统仿真,输出各个节点波形。
  • XML 现实案例:深入解析与应用
  • 斯坦福泡茶机器人DexCap源码解析:涵盖收集数据、处理数据、模型训练三大阶段
  • 【动手学电机驱动】STM32-FOC(5)基于 IHM03 的无感 FOC 控制
  • 【Chrono Engine学习总结】5-sensor-5.3-LiDAR扫描顺序、时间戳计算与去畸变
  • AttriPrompter:基于属性语义的自动提示,用于通过视觉-语言预训练模型实现零样本细胞核检测|文献速递-基于深度学习的病灶分割与数据超分辨率
  • 【JavaEE初阶】多线程上部
  • 使用wordpress搭建简易的信息查询系统