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

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,默认false
        logLevel: '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 {

    @GetMapping
    public 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 {

    @Override
    public 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 {

    @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);
    }
}

多路径配置示例

如果你有多个路径需要不同的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 www.example.com;  # 支持example.com和www.example.com访问

    # SSL重定向(可选),如果你有SSL证书并想强制HTTPS连接
    # if ($scheme = http) {
    #     return 301 https://$host$request_uri;
    # }

    root /var/www/html/dist;  # 设置默认的根目录,用于整个server块

    location / {
        try_files $uri $uri/ /index.html;  # 对于所有请求尝试匹配文件或目录,否则返回index.html以支持前端路由
    }

    location ^~ /api/  # 表示如果请求的 URI 以 /api/ 开头,则匹配该 location 块。 {
        rewrite ^/api/(.*)$ /$1 break; # 将所有以 /api/ 开头的请求(例如 /api/user)重写为去掉 /api/ 的路径(例如 /user)。
        proxy_pass http://backend.example.com;  # 将/api/开头的请求转发给后端API服务器
        proxy_set_header Host $host;  # 设置Host头信息为原始请求的Host
        proxy_set_header X-Real-IP $remote_addr;  # 设置X-Real-IP头信息为客户端的真实IP地址
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 添加X-Forwarded-For头信息包含客户端IP
        proxy_set_header X-Forwarded-Proto $scheme;  # 设置X-Forwarded-Proto头信息为请求协议(HTTP或HTTPS)
        
        # 如果你的后端需要知道请求是通过HTTPS来的,则确保这个头信息被正确传递
        # 如果使用了负载均衡器或反向代理链,可能需要调整此设置
    }

    # 错误页面定制(可选)
    error_page 404 /custom_404.html;
    location = /custom_404.html {
        internal;  # 只能由内部重定向到达,不能直接访问
    }

    # 日志格式(可选)
    access_log /var/log/nginx/example.com.access.log combined;
    error_log /var/log/nginx/example.com.error.log;

    # 其他安全相关的设置(可选)
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    # 对静态资源进行缓存(可选)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

步骤:

  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)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录第一次跑YOLOV8做目标检测

今天是24年的最后一天&#xff0c;终于要向新世界开始破门了&#xff0c;开始深度学习&#xff0c;YOLO来敲门~ 最近做了一些皮肤检测的功能&#xff0c;在传统的处理中经历了反复挣扎&#xff0c;终于要上YOLO了。听过、看过&#xff0c;不如上手体会过~ 1、YOLO是什么&#x…

从授权校验看SpringBoot自动装配

背景 最近需要实现一个对于系统的授权检测功能&#xff0c;即当SpringBoot应用被启动时&#xff0c;需要当前设备是否具有有效的的授权许可信息&#xff0c;若无则直接退出应用。具体的实现方案请继续看下文。 环境 Ruoyi-Vue SpringBoot3 RuoYi-Vue: &#x1f389; 基于Spr…

【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体

更新日期&#xff1a;2024年12月30日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 问题再现通过Tag搜索物体&#xff08;SearchByTag&#xff09;打开SearchByTag窗口搜索标记指定Tag的所有物体批量修改Tag搜索Undefined状态的所有物体 …

Unity2D无限地图的实现(简单好抄)

说明&#xff1a;本教程实现的是在2D游戏中玩家在游戏中上下左右移动的时候自动进行地图拼接的功能&#xff0c;如果你只想实现左右移动的无限地图&#xff0c;那么这篇博客也能起到一定参考作用。 思路 第一步&#xff1a; 创建一个10*10的2D游戏对象当做地图 第二步创建一个…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全&#xff1a;现代企业的必修课 在现代技术生态中&#xff0c;应用程序编程接口&#xff08;API&#xff09;扮演着不可或缺的角色。从数据共享到跨平台集成&#xff0c;API 成为连接企业系统与外部服务的桥梁。然而&#xff0c;伴随云计算的普及与微服务架构的流行…

日期时间选择(设置禁用状态)

目录 1.element文档需要 2.禁用所有过去的时间 3.设置指定日期的禁用时间 <template><div class"block"><span class"demonstration">起始日期时刻为 12:00:00</span><el-date-pickerv-model"value1"type"dat…

SAP学习笔记 - 豆知识14 - Msg 番号 M7562 - 取引Type WL 对应的番号範囲中不存在2025年度 OMBT

这种类似的以前也写过&#xff0c;原因就是自动採番的番号没弄。 比如跨年了&#xff0c;那该新年度的番号范围没弄啊&#xff0c;就会出这种错误。 把番号范围给加一下就可以了。 1&#xff0c;现象 比如点 VL02N 出荷传票变更 画面&#xff0c;点 出库确认 就会出如下错误…

SpringBoot 集成 Activiti 7 工作流引擎

一. 版本信息 IntelliJ IDEA 2023.3.6JDK 17Activiti 7 二. IDEA依赖插件安装 安装BPM流程图插件&#xff0c;如果IDEA的版本超过2020,则不支持actiBPM插件。我的IDEA是2023版本我装的是 Activiti BPMN visualizer 插件。 在Plugins 搜索 Activiti BPMN visualizer 安装 创…

分布式版本管理工具——Git关联远程仓库(github+gitee)

Git远程仓库&#xff08;Github&#xff09;的基本使用 一、前言二、Git远程仓库介绍三、演示1. 关联github远程仓库2. 关联gitee&#xff08;码云&#xff09;远程仓库3. 重命名远程仓库名4. 移除远程仓库 四、结束语 一、前言 古之立大事者&#xff0c;不惟有超世之才&#x…

python-leetcode-删除有序数组中的重复项 II

80. 删除有序数组中的重复项 II - 力扣&#xff08;LeetCode&#xff09; class Solution:def removeDuplicates(self, nums: List[int]) -> int:n len(nums)if n < 2:return n # 如果长度小于等于 2&#xff0c;直接返回长度k 2 # 指针 k 指向下一个有效位置&#x…

欧科云链OKLink:比特币与以太坊“双重启动”将如何撬动市场?

近日&#xff0c;OKLink 与 137Labs 联合举办 X Space&#xff0c;围绕宏观经济环境、政策及机构投资的影响等话题&#xff0c;分享如何把握 Web3 中的潜在机会与辨别风险。OKG Research 首席研究员 Hedy、BuilderRocket Accelerator 研究合伙人 Vivienna、VC 分析员 Bunny、BU…

【Linux】Socket编程-UDP构建自己的C++服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; UDP 网络编程 &#x1f98b; 接口讲解&#x1f98b; V1 版本 - echo server&#x1f98b; V2 版本 - DictServer&#x1f98b; V3 版本 - 简单聊天室 二&a…

创建型设计模式、结构型设计模式与行为型设计模式 上下文任务通用方案 设计模式 大全

设计模式&#xff08;Design Pattern&#xff09;是一种面向对象编程思想&#xff0c;分为创建型模式、结构型模式与行为型模式三大类&#xff0c;提供在特定上下文中解决常见任务通用方案&#xff0c;旨在让程序&#xff08;软件&#xff09;具有更好特点&#xff0c;如降低耦…

如何查看下载到本地的大模型的具体大小?占了多少存储空间:Llama-3.1-8B下载到本地大概15GB

这里介绍一下tree命令&#xff0c;可以方便的查看文件目录结构和文件大小。 命令行tree的具体使用&#xff0c;请参考笔者的另一篇博客&#xff1a;深入了解 Linux tree 命令及其常用选项&#xff1a;Linux如何显示目录结构和文件大小&#xff0c;一言以蔽之&#xff0c;sudo a…

MySQL线上事故:使用`WHERE`条件`!=xxx`无法查询到NULL数据

前言 在一次 MySQL 的线上查询操作中&#xff0c;因为 ! 的特性导致未能正确查询到为 NULL 的数据&#xff0c;险些引发严重后果。本文将详细解析 NULL 在 SQL 中的行为&#xff0c;如何避免类似问题&#xff0c;并提供实际操作建议。 1. 为什么NULL会查询不到&#xff1f; 在…

4G报警器WT2003H-16S低功耗语音芯片方案开发-实时音频上传

一、引言 在当今社会&#xff0c;安全问题始终是人们关注的重中之重。无论是家庭、企业还是公共场所&#xff0c;都需要一套可靠的安全防护系统来保障人员和财产的安全。随着科技的飞速发展&#xff0c;4G 报警器应运而生&#xff0c;为安全防范领域带来了全新的解决方案。…

U盘格式化工具合集:6个免费的U盘格式化工具

在日常使用中&#xff0c;U盘可能会因为文件系统不兼容、数据损坏或使用需求发生改变而需要进行格式化。一个合适的格式化工具不仅可以清理存储空间&#xff0c;还能解决部分存储问题。本文为大家精选了6款免费的U盘格式化工具&#xff0c;并详细介绍它们的功能、使用方法、优缺…

玩转OCR | 腾讯云智能结构化OCR初次体验

目录 一、什么是OCR&#xff08;需要了解&#xff09; 二、产品概述与核心优势 产品概述 智能结构化能做什么 举例说明&#xff08;选看&#xff09; 1、物流单据识别 2、常见证件识别 3、票据单据识别 4、行业材料识别 三、产品特性 高精度 泛化性 易用性 四、…

基于微信小程序的校园自助打印系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

driftingblues6_vh靶机

首先把靶机换成NAT模式 使用 arp-scan 命令扫描网段内存活的主机&#xff0c;以获取靶机ip地址 arp-scn -l 尝试访问ip 使用御剑扫描子域名&#xff0c;尝试访问robots.txt文件 通过访问文件我们发现了一个/textpattern/textpattern目录 访问一下目录发现了登录页面 他还给了…