vue2/3,Spring Boot以及生产环境跨域解决方案

news/2024/12/28 11:13:49/

vue2和vue3跨域解决方案

Vue 2 (基于 Webpack) 的跨域解决方案

1. 创建或编辑 vue.config.js 文件

Vue CLI为Webpack项目提供了简单的代理配置方式。你可以通过创建或编辑项目的根目录下的 vue.config.js 文件来设置开发服务器的代理规则:

// vue.config.js
module.exports = {devServer: {proxy: {'/api': { // 代理路径前缀target: 'http://backend.example.com', // 后端API的地址changeOrigin: true,                   // 更改请求源pathRewrite: { '^/api': '' },         // 重写路径,去掉/api前缀secure: false,                        // 如果后端是HTTPS,则设置为true,默认falselogLevel: 'debug'                     // 设置日志级别,方便调试}}}
};

2. 修改前端请求代码

确保你的前端请求都通过 /api 前缀发送,这样它们会被正确代理到后端服务器:

// 在Vue组件或API服务中
import axios from 'axios';export function fetchDepartments() {return axios.get('/api/depts').then(response => response.data).catch(error => console.error('There was an error!', error));
}

Vue 3 (基于 Vite) 的跨域解决方案

Vite使用了一种不同的方式来处理开发服务器的代理配置。它没有像Webpack那样内置的代理配置选项,但可以通过修改 vite.config.js 来实现相同的功能。

使用 Vite 的代理配置

1. 创建或编辑 vite.config.js 文件

你需要在 vite.config.js 中定义一个 server.proxy 属性:

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';export default defineConfig({plugins: [vue()],server: {proxy: {'/api': {target: 'http://backend.example.com',changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),},},},
});

2. 修改前端请求代码

同Vue 2一样,确保所有对后端的请求都通过 /api 前缀来发送:

// 在Vue组件或API服务中
import axios from 'axios';export function fetchDepartments() {return axios.get('/api/depts').then(response => response.data).catch(error => console.error('There was an error!', error));
}

Spring Boot 中的 CORS 配置详解

方法 1:使用 @CrossOrigin 注解(局部配置)

@CrossOrigin 注解是最简单的方式,适用于需要为特定控制器或方法启用CORS的情况。你可以通过在控制器类或方法上添加这个注解来实现。

局部配置示例

// src/main/java/com/example/demo/controller/MyController.java
package com.example.demo.controller;import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("/api/depts")
@CrossOrigin(origins = "https://example.com", maxAge = 3600) // 允许的源及缓存时间
public class MyController {@GetMappingpublic ResponseEntity<List<String>> getDepts() {List<String> depts = Arrays.asList("HR", "Finance", "IT");return ResponseEntity.ok(depts);}
}

注意事项

  • origins:指定允许的源。
  • maxAge:预检请求的结果可以被缓存的时间(以秒为单位)。
  • allowedHeaders:可选,指定允许的HTTP头。
  • methods:可选,指定允许的HTTP方法。
  • exposedHeaders:可选,指定哪些响应头可以暴露给浏览器。
  • allowCredentials:是否允许凭证(如Cookies)。如果设置为 true,则不能使用通配符 * 作为源。

完整注解参数

@CrossOrigin(origins = {"https://example.com"}, methods = {RequestMethod.GET, RequestMethod.POST},allowedHeaders = {"Authorization", "Content-Type"},exposedHeaders = {"X-Custom-Header"},allowCredentials = "true",maxAge = 3600
)

方法 2:全局配置 CORS(WebMvcConfigurer)

如果你想要为所有端点配置CORS,或者定义多个CORS配置,可以通过实现 WebMvcConfigurer 接口并重写 addCorsMappings 方法来进行全局配置。

全局配置示例

// src/main/java/com/example/demo/config/WebConfig.java
package com.example.demo.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 匹配所有路径.allowedOrigins("https://example.com") // 允许的源.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法.allowedHeaders("*") // 允许的HTTP头.allowCredentials(true) // 是否允许凭证.maxAge(3600); // 预检请求结果缓存时间(秒)}
}

注意事项

  • allowedOrigins:指定允许的源,可以是一个具体的URL,也可以是通配符 * 表示允许所有源。但是,如果你启用了凭证共享 (allowCredentials=true),则不能使用通配符 *
  • allowedMethods:指定允许的HTTP方法。
  • allowedHeaders:指定允许的HTTP头。
  • allowCredentials:如果设置为 true,则意味着响应将包含 Access-Control-Allow-Credentials 头,这会告诉浏览器是否允许发送凭证信息(例如cookies)。如果启用了凭证,则不能将 allowedOrigins 设置为 *
  • maxAge:预检请求的结果可以被缓存的时间(以秒为单位)。

多路径配置示例

如果你需要为不同路径设置不同的CORS规则,可以在 addCorsMappings 方法中注册多个映射:

@Override
public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**").allowedOrigins("https://example.com").allowedMethods("GET", "POST").allowedHeaders("Authorization", "Content-Type").allowCredentials(true).maxAge(3600);registry.addMapping("/admin/**").allowedOrigins("https://admin.example.com").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(false).maxAge(3600);
}

方法 3:通过 CorsFilter 配置

对于更复杂的场景,比如你需要对不同的路径应用不同的CORS规则,或者你希望在应用程序启动时就注册CORS过滤器,你可以创建一个 CorsConfigurationSource 并注册一个 CorsFilter

自定义 CorsFilter 示例

// src/main/java/com/example/demo/config/CorsConfig.java
package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();// Path 1: /api/*CorsConfiguration apiConfig = new CorsConfiguration();apiConfig.setAllowCredentials(true);apiConfig.addAllowedOrigin("https://example.com");apiConfig.addAllowedHeader("Authorization");apiConfig.addAllowedHeader("Content-Type");apiConfig.addAllowedMethod("GET");apiConfig.addAllowedMethod("POST");source.registerCorsConfiguration("/api/**", apiConfig);// Path 2: /admin/*CorsConfiguration adminConfig = new CorsConfiguration();adminConfig.setAllowCredentials(false);adminConfig.addAllowedOrigin("https://admin.example.com");adminConfig.addAllowedHeader("*");adminConfig.addAllowedMethod("*");source.registerCorsConfiguration("/admin/**", adminConfig);return new CorsFilter(source);}
}

多路径配置示例

如果你有多个路径需要不同的CORS规则,可以在 UrlBasedCorsConfigurationSource 中注册多个配置:

@Bean
public CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();// Path 1: /api/*CorsConfiguration apiConfig = new CorsConfiguration();apiConfig.setAllowCredentials(true);apiConfig.addAllowedOrigin("https://example.com");apiConfig.addAllowedHeader("Authorization");apiConfig.addAllowedHeader("Content-Type");apiConfig.addAllowedMethod("GET");apiConfig.addAllowedMethod("POST");source.registerCorsConfiguration("/api/**", apiConfig);// Path 2: /admin/*CorsConfiguration adminConfig = new CorsConfiguration();adminConfig.setAllowCredentials(false);adminConfig.addAllowedOrigin("https://admin.example.com");adminConfig.addAllowedHeader("*");adminConfig.addAllowedMethod("*");source.registerCorsConfiguration("/admin/**", adminConfig);return new CorsFilter(source);
}

高级配置选项

1. 处理凭证共享

当你需要处理凭证(如Cookies)时,确保正确设置了 allowCredentialsallowedOrigins。记住,如果启用了凭证共享,你不能使用通配符 * 作为允许的源。

config.setAllowCredentials(true);
config.addAllowedOrigin("https://example.com"); // 必须明确指定源
2. 处理复杂头部

有时你需要处理特定的HTTP头部,而不是简单的通配符。你可以通过 setAllowedHeaders 方法来指定允许的头部。

config.addAllowedHeader("Authorization");
config.addAllowedHeader("Content-Type");
3. 处理多种来源

如果你有多个允许的来源,可以使用 setAllowedOrigins 方法来添加多个源。

config.addAllowedOrigin("https://example.com");
config.addAllowedOrigin("https://anotherdomain.com");
4. 处理预检请求

预检请求(Preflight Requests)是在某些跨域请求之前由浏览器自动发送的,用于检查服务器是否允许实际请求。你可以通过 setAllowCredentialssetMaxAge 来控制这些行为。

config.setAllowCredentials(true);
config.setMaxAge(3600L); // 缓存预检请求结果的时间(秒)
5. 暴露特定响应头

有时候你需要让客户端能够访问某些特定的响应头。你可以通过 setExposedHeaders 方法来指定这些响应头。

config.setExposedHeaders(Arrays.asList("X-Custom-Header"));

生产环境下的解决方案

1. 使用 Nginx 反向代理

Nginx 是一个高性能的HTTP和反向代理服务器,它可以帮助你将前端请求转发到后端API服务器,同时处理跨域问题。通过这种方式,你可以确保所有的请求都来自同一个域名,从而避免浏览器的同源策略限制。

Nginx 配置示例

假设你的前端应用部署在 http://example.com,而后端API位于 http://backend.example.com。你可以使用Nginx来设置反向代理:

# /etc/nginx/sites-available/example.com
server {listen 80;server_name example.com;location / {# 将所有前端静态资源请求指向Vue构建的静态文件目录root /var/www/html/dist;try_files $uri $uri/ /index.html;}location /api/ {# 将/api/开头的请求转发给后端API服务器proxy_pass http://backend.example.com/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}

步骤:

  1. 安装 Nginx(如果尚未安装):

    sudo apt update
    sudo apt install nginx
  2. 配置 Nginx

    • 创建或编辑 /etc/nginx/sites-available/example.com 文件。
    • 使用上述配置示例进行修改,确保路径和域名正确。
  3. 启用站点配置

    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
  4. 测试配置并重启 Nginx

    sudo nginx -t
    sudo systemctl restart nginx
  5. 部署前端静态文件

    • 将Vue构建后的静态文件放置在 /var/www/html/dist 目录下。
  6. 确保后端API服务器正常运行

    • 确认 http://backend.example.com 可以访问,并且API服务正常工作。

2. 前后端部署在同一域名下

如果可能的话,将前后端部署在同一域名下是解决跨域问题的最佳实践之一。这样做可以完全避免跨域问题,因为所有请求都来自同一源。

示例:

  • 前端:部署在 https://example.com
  • 后端API:部署在 https://api.example.com

如果你使用的是子域名(如 api.example.com),你可以通过DNS配置和SSL证书来确保它们被视为同一源。另外,也可以考虑将API路由集成到主域名中(例如 https://example.com/api)。


http://www.ppmy.cn/news/1558772.html

相关文章

第七节:GLM-4v-9b模型的视觉模型源码解读

文章目录 前言一、EVA2CLIPModel视觉编码模块结构二、PatchEmbedding图像分块源码解读三、GLM的transformer结构源码解读四、GLU映射方法源码解读前言 清华智普的GLM-4v-9b模型,作为优化的多模态大模型,特别适用于国内应用场景,解决了国外模型本地化不足的问题。本专栏提供…

Docker离线安装简易指南

Docker离线安装简易指南&#xff1a; &#x1f4e6; 下载安装包&#xff1a;浏览器访问Docker官网下载https://download.docker.com/linux/static/stable/x86_64/docker-27.4.1.tgz &#xff0c;并上传服务器 scp docker-27.4.1.tgz root服务器IP:/服务器目录/&#x1f4be; 解…

掌握Docker命令与Dockerfile实战技巧:快速构建高效容器化应用

1. 介绍 Docker 是现代开发和运维的必备工具&#xff0c;集成了容器技术的优势。本文将记录 Docker 的常用指令&#xff0c;并会随着使用经验的积累进行不定期更新。 2. 常用命令 2.1 启动容器&#xff08;前台交互模式&#xff09; docker run --privileged --volume /hom…

npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本

npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1&#xff0c;因为在此系统上禁止运行脚本 1、问题详情 npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1&#xff0c;因为在此系统上禁止运行脚本&#xff0c;具体如下图所示&#xff1a; 2、解决方法 1.使用命令 get-Ex…

PDF书籍《手写调用链监控APM系统-Java版》第7章 插件与链路的结合:Tomcat插件实现

本人阅读了 Skywalking 的大部分核心代码&#xff0c;也了解了相关的文献&#xff0c;对此深有感悟&#xff0c;特此借助巨人的思想自己手动用JAVA语言实现了一个 “调用链监控APM” 系统。本书采用边讲解实现原理边编写代码的方式&#xff0c;看本书时一定要跟着敲代码。 作者…

Vue 3 具名插槽传值详解

Vue 3 具名插槽传值详解 Vue 3 的具名插槽不仅支持内容插入&#xff0c;还支持通过作用域插槽传递值&#xff08;又称插槽作用域&#xff09;。这使得父组件能够动态接收来自子组件的数据&#xff0c;从而实现更加灵活的组件开发。 在本文中&#xff0c;我们将深入讲解 Vue 3…

《人工智能如何加速药物研发进程:从新药发现到临床试验的突破》

在当今医药领域&#xff0c;药物研发的复杂性和高成本使得新药的推出面临诸多挑战。而人工智能&#xff08;AI&#xff09;正以其强大的能力为药物研发带来新的契机&#xff0c;助力加速新药发现和临床试验过程。 新药发现阶段 靶点识别与筛选 药物研发的第一步是确定药物作…

蓝桥杯速成教程{三}(adc,i2c,uart)

目录 一、adc 原理图​编辑引脚配置 Adc通道使能配置 实例测试 ​编辑效果显示 案例程序 badc 按键相关函数 测量频率占空比 main 按键的过程 显示界面的过程 二、IIC通信-eeprom 原理图AT24C02 引脚配置 不可用状态&#xff0c;用的软件IIC 官方库移植 At24c02手册 ​编辑…