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

谷粒商城实战笔记-47-商品服务-API-三级分类-网关统一配置跨域

文章目录

  • 一,跨域问题
    • 1,跨域问题产生的原因
    • 2,预检请求
    • 3,跨域解决方案
      • 3.1 CORS (Cross-Origin Resource Sharing)
        • 后端配置示例(Spring Boot)
      • 3.2 JSONP (JSON with Padding)
      • 3.3 代理服务器
        • Nginx代理配置示例
      • 3.4 Server-Side Proxy (后端代理)
      • 3.5 使用WebSocket
      • 3.6 PostMessage API
      • 3.7 CORS Anywhere
  • 二,解决方案

一,跨域问题

当上一节设置好通过网关转发请求后,点击登录按钮,无法登录。

浏览器控制台有报错信息,如下。

在这里插入图片描述

图上的信息表明出现了跨域问题

跨域问题是Web开发中常见的问题,尤其在前后端分离的架构中更为突出。

以“谷粒商城”为例,前端应用和后端服务部署分开部署,端口号不同。当前端应用尝试从后端API请求数据时,就会遇到跨域问题。

1,跨域问题产生的原因

浏览器出于安全考虑,实施了同源策略(Same-Origin Policy)。

根据同源策略,来自不同源(协议、域名、端口任意一项不同即视为不同源)的HTTP请求被限制,不能相互读取或写入对方的资源。

一定要协议、域名或者IP、端口都一致时,才不会被同源策略限制,可参考下面列表。

在这里插入图片描述

上面的例子中,首先访问前端项目,端口是8001,打开登录界面后,点击登录,登录接口会发给网关,网关的端口是80,根据同源策略,端口不同不允许访问,会被浏览器限制访问。

2,预检请求

在这里插入图片描述

上面图片中的OPTIONS,说明这个请求是个预检请求。

为什么需要预检请求呢?

原因是同源策略是浏览器的安全策略,在不同源的情况下,服务器端如果允许跨域的话,浏览器仍然可以发出跨域请求。

如果不同源,浏览器先发送一个轻量级的预检请求,询问服务器是否允许跨域访问,如果允许跨域访问,才会真正的发出请求。

在这里插入图片描述

上图图描述了非简单请求(如PUT、DELETE等)的跨域过程,具体来说,这是一个典型的CORS(Cross-Origin Resource Sharing)预检请求的过程。下面是详细的解释:

  1. 预检请求,OPTIONS
    浏览器发送一个预检请求(OPTIONS),询问服务器是否允许跨域请求。这个请求带有特殊的HTTP头,比如Origin表示请求来源的URL,以及Access-Control-Request-Method表示实际请求将使用的HTTP方法。

  2. 响应允许跨域
    服务器收到预检请求后,检查请求头,如果满足条件(如允许的源、方法、请求头等),则返回一个成功的响应,包含Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers等头,表明允许跨域请求。如果服务器不允许跨域,则返回一个失败的响应。

  3. 发送真实请求
    如果预检请求得到允许,浏览器才会发送真实的HTTP请求(如PUT或DELETE),携带实际的数据。

  4. 响应数据
    服务器处理完请求后,返回响应数据。此时,响应头中应包含Access-Control-Allow-Origin等头,确认允许跨域。

这个过程是为了保护用户的安全,防止恶意网站窃取敏感数据。只有在预检请求得到允许后,浏览器才会发送真正的请求。对于简单请求(如GET、POST),浏览器可以直接发送,不需要预检请求。但对于非简单请求,浏览器必须先验证服务器是否允许跨域,以确保用户的隐私和安全。

3,跨域解决方案

只要浏览器允许跨域,浏览器就可以发出跨域请求。

解决跨域问题的常见方法有以下几种:

3.1 CORS (Cross-Origin Resource Sharing)

CORS 是一种最常用的跨域解决方案,允许服务器通过响应头来指定哪些源可以访问其资源。

服务器需要在响应中添加Access-Control-Allow-Origin头来指明哪些源可以访问资源。

此外,还可以设置Access-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Allow-Credentials等头来细化跨域访问的控制。

后端配置示例(Spring Boot)
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*") // 或指定的源.allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(false).maxAge(3600);}
}

3.2 JSONP (JSON with Padding)

JSONP是一种用于绕过同源策略的技巧,但它仅限于GET请求。前端向服务器发送一个GET请求,服务器将数据包裹在回调函数中返回。这种方式的安全性较低,且不支持POST等其他HTTP方法。

3.3 代理服务器

通过设置一个代理服务器(如Nginx或Node.js的Express应用),前端向代理服务器发送请求,代理服务器再向实际的后端API发送请求。这样前端和后端看似在同一源下通信,绕过了同源策略的限制。

Nginx代理配置示例
location /api/ {proxy_pass http://backend_server;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;
}

3.4 Server-Side Proxy (后端代理)

在后端API中添加逻辑,将请求转发到另一个源。这通常用于微服务架构中,一个服务充当其他服务的代理。

3.5 使用WebSocket

WebSocket协议不受同源策略的限制,可以用于建立持久的双向通信通道,适用于实时数据传输场景。

3.6 PostMessage API

HTML5引入的postMessageAPI允许不同源的窗口之间进行安全通信,通常用于iframe之间的通信。

3.7 CORS Anywhere

CORS Anywhere是一个开源的Node.js中间件,可以作为代理服务器,自动添加CORS响应头,使得任何源都可以访问资源。但它可能涉及安全和隐私问题,应当谨慎使用。

我们采用第一种方案。

二,解决方案

考虑到所有的请求都会经过网关,所以可以在网关设置允许跨域,这样就不需要在每一个服务都进行跨域配置了。

我们通过创建一个配置类,在配置类中创建一个过滤器,过滤器给经过的所有请求的请求头加上允许跨域的信息。

在这里插入图片描述

配置类代码如下。

package com.atguigu.gulimall.gateway.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;@Configuration
public class GulimallCorsConfiguration {@Beanpublic CorsWebFilter corsWebFilter(){UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();//1、配置跨域corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");corsConfiguration.addAllowedOriginPattern("*");corsConfiguration.setAllowCredentials(true);source.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(source);}
}

经过这样设置之后,再次操作,就顺利登录了。

相关文章:

谷粒商城实战笔记-47-商品服务-API-三级分类-网关统一配置跨域

文章目录 一,跨域问题1,跨域问题产生的原因2,预检请求3,跨域解决方案3.1 CORS (Cross-Origin Resource Sharing)后端配置示例(Spring Boot) 3.2 JSONP (JSON with Padding)3.3 代理服务器Nginx代理配置示例…...

stm32平台为例的软件模拟时间,代替RTC调试

stm32平台为例的软件模拟时间,代替RTC调试 我们在开发项目的时候,如果用到RTC,如果真正等待RTC到达指定的时间,那调试时间就太长了。 比如每隔半个小时,存储一次数据,如果要观察10次存储的效果&#xff0…...

《设计模式之美》读书笔记2

从Linux学习应对大型复杂项目的方法: 1、封装与抽象:封装了不同类型设备的访问细节,抽象为统一的文件访问方式,更高层的代码就能基于统一的访问方式,来访问底层不同类型的设备。这样做的好处是,隔离底层设备…...

C++ STL set_difference 用法

一&#xff1a;功能 给定两个集合A&#xff0c;B&#xff1b;计算集合的差集&#xff0c;即计算出那些只包含在A中而不包含在B中的元素。 二&#xff1a;用法 #include <vector> #include <algorithm> #include <iostream>int main() {std::vector<int&…...

【基础算法总结】优先级队列

优先级队列 1.最后一块石头的重量2.数据流中的第 K 大元素4.前K个高频单词4.数据流的中位数 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1…...

python-绝对值排序(赛氪OJ)

[题目描述] 输入 n 个整数&#xff0c;按照绝对值从大到小排序后输出。保证所有整数的绝对值不同。输入格式&#xff1a; 输入数据有多组&#xff0c;每组占一行&#xff0c;每行的第一个数字为 n ,接着是 n 个整数&#xff0c; n0 表示输入数据的结束&#xff0c;不做处理。输…...

成功者的几个好习惯,你具备了几个

每个人都想成为自己领域的佼佼者&#xff0c;然而&#xff0c;成功并非偶然&#xff0c;它往往与一系列良好的习惯紧密相连。这些习惯如同灯塔&#xff0c;指引着成功者在波涛汹涌的大海中稳健前行。 一、设定明确目标 没有明确的目标&#xff0c;就如同航海没有指南针&#…...

centos中zabbix安装、卸载及遇到的问题

目录 Zabbix简介Zabbix5.0和Zabbix7.0的区别监控能力方面模板和 API 方面性能、速度方面 centos7安装Zabbix(5.0)安装zabbix遇到的问题卸载Zabbix Zabbix简介 Zabbix 是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix 能监视各种网络参…...

php编译安装

一、基础环境准备 # php使用www用户 useradd -s /sbin/nologin -M www二、下载php包 # 下载地址 https://www.php.net/downloads wget https://www.php.net/distributions/php-8.3.9.tar.gz三、配置编译安装 编译安装之前需要处理必要的依赖&#xff0c;在编译配置安装&…...

[K8S] K8S资源控制器Controller Manager(4)

文章目录 1. 常见的Pod控制器及含义2. Replication Controller控制器2.1 部署ReplicaSet 3. Deployment3.1部署Deployment3.2 运行Deployment3.3 镜像更新方式3.4 Deployment扩容3.5 滚动更新3.6 金丝雀发布(灰度发布)3.7 Deployment版本回退3.8 Deployment 更新策略 4. Daemon…...

C#,.NET常见算法

1.递归算法 1.1.C#递归算法计算阶乘的方法 using System;namespace C_Sharp_Example {public class Program{/// <summary>/// 阶乘&#xff1a;一个正整数的阶乘Factorial是所有小于以及等于该数的正整数的积&#xff0c;0的阶乘是1&#xff0c;n的阶乘是n&#xff0…...

KubeSphere介绍及一键安装k8s

KubeSphere介绍 官网地址&#xff1a;https://kubesphere.io/zh/ KubeSphere愿景是打造一个以 Kubernetes 为内核的云原生分布式操作系统&#xff0c;它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用&#xff08;plug-and-play&#xff09;的集成&#xff0…...

Spring 系列

SpringBoot 实体类&#xff08;Entity&#xff09;层 实体类&#xff08;Entity&#xff09;通常属于模型层&#xff08;Model Layer&#xff09;或领域层&#xff08;Domain Layer&#xff09;。它们代表应用程序中的核心业务数据结构&#xff0c;与数据库表结构紧密对应。在…...

基于opencv[python]的人脸检测

1 图片爬虫 这里的代码转载自&#xff1a;http://t.csdnimg.cn/T4R4F # 获取图片数据 import os.path import fake_useragent import requests from lxml import etree# UA伪装 head {"User-Agent": fake_useragent.UserAgent().random}pic_name 0 def request_pic…...

配置SSH公钥互信

目录 第一台主机&#xff1a;servera&#xff08;172.25.250.101&#xff09; 第一步&#xff1a;查看 . ssh目录下面是否为空 第二步&#xff1a;输入命令ssh-keygen 第三步&#xff1a; 再看查看一下. ssh目录 第四步&#xff1a; 输入命令 ssh-copy-id root172.25.250…...

WEB渗透Web突破篇-SQL注入(MSSQL)

注释符 -- 注释 /* 注释 */用户 SELECT CURRENT_USER SELECT user_name(); SELECT system_user; SELECT user;版本 SELECT version主机名 SELECT HOST_NAME() SELECT hostname;列数据库 SELECT name FROM master..sysdatabases; SELECT DB_NAME(N); — for N 0, 1, 2, ……...

DAY15

数组 冒泡排序 冒泡排序无疑是最为出名的排序算法之一&#xff0c;总共有八大排序 冒泡的代码还是相当简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比较&#xff0c;江湖中人人尽皆知 我们看到嵌套循环&#xff0c;应该马上就可以得到这个算法的…...

pytest结合allure-pytest插件生成测试报告

目录 一、安装allure-pytest插件 二、下载allure 三、生成allure报告 四、效果展示 一、安装allure-pytest插件 二、下载allure 下载之后解压&#xff0c;解压之后还要配置环境变量&#xff08;把allure目录下bin目录配置到系统变量的path路径&#xff09;&#xff0c;下…...

详细解析用户提交咨询

上一篇文章中写到了使用Server-Sent Events (SSE)&#xff0c;并获取message里面的内容。 本篇文章主要是写&#xff0c;具体该如何实现的具体代码&#xff0c;代码见下方&#xff0c;可直接拿 async submitConsult() {this.scrollToBottom();if (!this.$checkLogin()) return;…...

UDP/TCP协议解析

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...