网站流程图制作软件,给个网站你们会感谢我的,企业所得税怎么征收税率,网站访问量怎么增加文章目录 一#xff0c;跨域问题1#xff0c;跨域问题产生的原因2#xff0c;预检请求3#xff0c;跨域解决方案3.1 CORS (Cross-Origin Resource Sharing)后端配置示例#xff08;Spring Boot#xff09; 3.2 JSONP (JSON with Padding)3.3 代理服务器Nginx代理配置示例… 文章目录 一跨域问题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 使用WebSocket3.6 PostMessage API3.7 CORS Anywhere 二解决方案 一跨域问题
当上一节设置好通过网关转发请求后点击登录按钮无法登录。
浏览器控制台有报错信息如下。 图上的信息表明出现了跨域问题。
跨域问题是Web开发中常见的问题尤其在前后端分离的架构中更为突出。
以“谷粒商城”为例前端应用和后端服务部署分开部署端口号不同。当前端应用尝试从后端API请求数据时就会遇到跨域问题。
1跨域问题产生的原因
浏览器出于安全考虑实施了同源策略Same-Origin Policy。
根据同源策略来自不同源协议、域名、端口任意一项不同即视为不同源的HTTP请求被限制不能相互读取或写入对方的资源。
一定要协议、域名或者IP、端口都一致时才不会被同源策略限制可参考下面列表。 在上面的例子中首先访问前端项目端口是8001打开登录界面后点击登录登录接口会发给网关网关的端口是80根据同源策略端口不同不允许访问会被浏览器限制访问。
2预检请求 上面图片中的OPTIONS说明这个请求是个预检请求。
为什么需要预检请求呢
原因是同源策略是浏览器的安全策略在不同源的情况下服务器端如果允许跨域的话浏览器仍然可以发出跨域请求。
如果不同源浏览器先发送一个轻量级的预检请求询问服务器是否允许跨域访问如果允许跨域访问才会真正的发出请求。 上图图描述了非简单请求如PUT、DELETE等的跨域过程具体来说这是一个典型的CORSCross-Origin Resource Sharing预检请求的过程。下面是详细的解释 预检请求OPTIONS 浏览器发送一个预检请求OPTIONS询问服务器是否允许跨域请求。这个请求带有特殊的HTTP头比如Origin表示请求来源的URL以及Access-Control-Request-Method表示实际请求将使用的HTTP方法。 响应允许跨域 服务器收到预检请求后检查请求头如果满足条件如允许的源、方法、请求头等则返回一个成功的响应包含Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等头表明允许跨域请求。如果服务器不允许跨域则返回一个失败的响应。 发送真实请求 如果预检请求得到允许浏览器才会发送真实的HTTP请求如PUT或DELETE携带实际的数据。 响应数据 服务器处理完请求后返回响应数据。此时响应头中应包含Access-Control-Allow-Origin等头确认允许跨域。
这个过程是为了保护用户的安全防止恶意网站窃取敏感数据。只有在预检请求得到允许后浏览器才会发送真正的请求。对于简单请求如GET、POST浏览器可以直接发送不需要预检请求。但对于非简单请求浏览器必须先验证服务器是否允许跨域以确保用户的隐私和安全。
3跨域解决方案
只要浏览器允许跨域浏览器就可以发出跨域请求。
解决跨域问题的常见方法有以下几种
3.1 CORS (Cross-Origin Resource Sharing)
CORS 是一种最常用的跨域解决方案允许服务器通过响应头来指定哪些源可以访问其资源。
服务器需要在响应中添加Access-Control-Allow-Origin头来指明哪些源可以访问资源。
此外还可以设置Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-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);}
}
经过这样设置之后再次操作就顺利登录了。