浏览器同源策略导致跨域问题 No ‘Access-Control-Allow-Origin‘ header 原因及解决方式--(后端、nginx、前端)

这篇具有很好参考价值的文章主要介绍了浏览器同源策略导致跨域问题 No ‘Access-Control-Allow-Origin‘ header 原因及解决方式--(后端、nginx、前端)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

现象

原因

浏览器同源策略

导致结果:

解决方案

跨源资源共享(CORS)

各个端解决方法:

后端:

方式1:重载WebMvcConfigurer方法

方式2:配置监听CorsFilter

方式3:相关类上加注解 @CrossOrigin

注意事项:

Nginx解决:

情况1:

前端解决:


现象

本人身份:后端

今天部署线上环境前端代码时,发生了如下报错:

Access to XMLHttpRequest at 'http://192.168.1.11:8081/api/v1/sys/auth/login' from origin 'http://192.168.1.8:8101' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

经典的跨域问题,=探究一下这个现象的本质以及从3个端(后端、代理、前端)分别该怎么处理这个问题

no 'access-control-allow-origin' header,前端,nginx,spring boot,运维,后端

 这个问题其实在开发环境是不会出现的,当把前端代码打包好后部署到线上环境,用Nginx跑起来后,发生了这个问题,发生这个问题的根本原因是由于浏览器的同源策略

原因

浏览器同源策略

同源策略(Same Origin Policy)是一种安全策略,它是浏览器最核心也是最基本的安全功能。同源策略会阻止一个域的javascrip脚本和另一个域的内容进行交互,是用于隔离潜在恶意文件的关键安全机制;关于这一点我们后面会举例说明。如果缺少了同源策略浏览器的安全使用会受到很大的影响。可以说web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源的三个条件:

域名、协议、端口都相同

假设 URL  A: http://192.168.1.8:8080/

下列URL与A是否同源比较

B


https://192.168.1.8:8080/

不同源,协议不同,一个是http,一个是https
C http://192.168.1.8:8081/ 不同源,端口号不同
D http://192.168.1.9:8080/ 不同源,IP不同
E http://192.168.1.8:8080/api  同源

导致结果:

  • 不能获取不同源的 cookie,LocalStorage 和 indexDB
  • 不能获取不同源的 DOM()
  • 不能发送不同源的 ajax 请求 (可以向不同源的服务器发起请求,但是返回的数据会被浏览器拦截)

上述的现象就是因为 ajax请求其实已经到了后端,后端也已经处理,但是因为浏览器的同源策略导致拒绝接收数据,所以其实这个现象在移动端不会出现,只会在浏览器出现

解决方案

其他方案如前端jsonp之类的方法,都有或大或小的弊端,看了比较久,介绍下面的方法

跨源资源共享(CORS)

Cross-Origin Resource Sharing 跨资源共享,作为W3C的标准,是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。是跨域ajax的根本解决方法,允许任何类型的请求。

客户端和服务器之间使用 CORS 首部字段来处理权限:

先看一个http的请求头和响应头

请求头:

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example

请求首部字段 Origin 表明该请求来源于 http://foo.example。而现在的VUE项目中都会默认带上这个请求头。

响应头:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被 任意 外域访问,当然,不建议配置 * ,当响应的是附带身份凭证的请求时,即withCredentials为true时,服务端 必须 明确 Access-Control-Allow-Origin 的值,而不能使用通配符“*”。

注:

exposedHeaders:

这个是暴露的头部列表,其中包含零个或多个头部名称,如果不设置,会出现你在F12的network里面能看到设置的响应头,但是前端仍然拿不到。多用于文件下载等需要拿到响应头中文件名称的场景下

各个端解决方法:

后端:

后端是基于Springboot开发,提供了这么几种方式来配置 cros

为了灵活配置,先做一个配置文件:application-security.yml

lc:  
   cors:
    allow-credential: true
    allow-mapping: '/**'
    allow-method: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
    allow-origin-pattern: http://192.168.1.11:8101,http://localhost:3002
    allow-header: '*'
    exposed-header: content-disposition
    max-age: 1800

properties文件

@Data
@ConfigurationProperties(prefix = "lc.cors")
public class CorsProperties {

    @NotNull
    private Boolean enable = true;

    private String allowMapping;

    private List<String> allowOriginPattern;

    private List<String> allowMethod;

    private List<String> allowHeader;

    private List<String> exposedHeader;

    @ApiModelProperty("单位:秒")
    private Long maxAge;

    private boolean allowCredential = true;
}

方式1:重载WebMvcConfigurer方法

这种我感觉是最合适的

@Configuration
@EnableConfigurationProperties(CorsProperties.class)
public class CorsConfig {

    @Autowired
    private CorsProperties corsProperties;

    @Bean
    public WebMvcConfigurer corsConfigurer() {

        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {

                registry.addMapping(corsProperties.getAllowMapping())
                        .allowedOriginPatterns(corsProperties.getAllowOriginPattern().toArray(new String[0]))
                        .allowCredentials(corsProperties.isAllowCredential())
                        .allowedMethods(corsProperties.getAllowMethod().toArray(new String[0]))
                        .allowedHeaders(corsProperties.getAllowHeader().toArray(new String[0]))
                        ..exposedHeaders(corsProperties.getExposedHeader().toArray(new String[0]))
                        .maxAge(corsProperties.getMaxAge());
            }
        };
    }
}

方式2:配置监听CorsFilter

 @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }

方式3:相关类上加注解 @CrossOrigin


@CrossOrigin
@Controller
@RequestMapping("/problem")
@ResponseBody
public class ProblemController implements Serializable {
 
	
	}

注意事项:

allow-origin-pattern这个属性配置时,尽量不要配置*,也许考虑到联调和线上环境的ip都要添加上

Nginx解决:

nginx解决主要是这个思路,nginx的实际原理就是配置一个代理路径替换实际的访问路径,使得浏览器认为访问的资源都是属于相同协议,域名和端口的,而实际访问的并不是代理路径,而是通过代理路径找到实际路径进行访问,所以,不妨将nginx看作是给浏览器的一种障眼法

情况1:

因为首先访问的是nginx的index.html,这种情况是不会产生跨域问题的,但是访问接口时,因为是调用的后端的接口,所以会产生跨域问题,这时候,我们将所有的接口配置一个代理,转发到实际的后端接口地址。

比如我们nginx配置的前端访问地址为:http://192.168.1.11:8080/api/

                              后端的接口地址为: http://192.168.1.11:8081/api/

下面是nginx的配置文件 nginx.conf,其实就是访问首页时,访问的还是index.html,但是访问具体的url时,nginx帮我们做一层转发,这样子就可以了。也不用加什么【add_header Access-Control-Allow-Origin *;】这样的响应头,因为此时nginx的代理会让浏览器认为是同源的路径

server {
	listen 8101;
	client_max_body_size 20m;
	location / {
		root /usr/share/nginx/html;
		index index.html index.htm;
	}
	location /api/ {
		proxy_pass http://192.168.1.11:8081/api/;
	}
	
}

前端解决:

1、JSONP

这种方式需要前后端配合解决,已经不推荐

2、代理

通过配置代理服务,下面几种方式

1、通过nginx来配置,需要相关技术栈

2、可以通过 vue-cli来配置,vue.config.js文件

devServer: {
proxy: 'http://192.168.1.111:8001'
}文章来源地址https://www.toymoban.com/news/detail-819366.html

到了这里,关于浏览器同源策略导致跨域问题 No ‘Access-Control-Allow-Origin‘ header 原因及解决方式--(后端、nginx、前端)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浏览器安全之同源策略

    原文合集地址如下,有需要的朋友可以关注 本文地址 合集地址 浏览器的同源策略是一种安全机制,用于保护用户信息和防止恶意代码的执行。它是由浏览器实施的一组规则,限制了不同源(origin)的网页之间的交互。 同源是指两个网页具有相同的协议(protocol),主机(

    2024年02月11日
    浏览(46)
  • 浏览器不同源的页面之间如何跨域通信

    现在有2个项目,页面路径不同源。 ToC 的收银台项目 类似在PC端京东淘宝,支付最后一步的收银台页面,可以选择不同支付工具付款。 ToB 的后台管理项目 可以对收银台项目整体做一些配置:样式,支付工具相关的等等,配置项很多。 需求 想要在后台管理项目中增删配置项

    2024年02月14日
    浏览(36)
  • 浏览器安全-同源策略和CORS

    同源策略是浏览器的一个安全功能,浏览器禁止在当前域读写其他域的资源,如限制跨域发送ajax请求 不受同源策略限制的 1)页面中的链接,重定向表单以及表单提交 2)跨域资源引入 如script不受跨域限制,可以跨域请求src 如何解决跨域访问资源 1)利用script的跨域特性绕过

    2024年02月09日
    浏览(44)
  • 浏览器跨域问题

    违背 同源策略 就是跨域。 同源策略 : 网页的url 和 该网页请求的url 的协议、域名、端口必须保持一致。 协议、域名、端口必须保持一致. 同源策略存在的原因: 保护用户隐私和防范网络攻击(https://editor.csdn.net/md?not_checkout=1spm=1011.2415.3001.6217articleId=132763789) 即如果网页请求的

    2024年02月09日
    浏览(33)
  • 最新版本chrome浏览器出现的跨域问题及解决方案

    最近将chrome浏览器更新到了最新版本 ,在个别网站上出现了跨域访问问题。 目录 解决办法: (1)增加参数配置代码 (2)重新打开浏览器 在桌面快捷方式中右键》属性》快捷方式中的目标后面加入以下参数配置代码 注意:其中chrome.exe与--disable之间有一个空格 然后重新打

    2024年02月06日
    浏览(57)
  • 解决浏览器自动将http跳转至https导致无法访问的问题

    目录 解决方式 Chrome浏览器 Safari浏览器 Edge浏览器 注意事项 什么是HSTS? 写在最后         最近在宝塔面板申请免费的SSL证书后,部署证书的80端口下的网站可以通过https正常访问,但其他未部署证书的端口也被强制跳转至https请求,导致浏览器提示不安全从而无法访问。

    2024年02月03日
    浏览(87)
  • 同浏览器下多窗口进行跨源通信、同源通信

    多页面通信运用到了“发布订阅”的设计模式,一个页面发布指令,其他页面进行订阅并进行相应的行为操作! window.postMessage() window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口

    2024年02月08日
    浏览(35)
  • Ajax同源策略及跨域问题

    其他AJAX知识 Ajax-概念、Http协议、Ajax请求及其常见问题——点击此处 AJAX请求的不同发送方式——点击此处 同源策略(Same-Origin Policy)是一种安全策略,是指: 协议 、 域名 、 端口 ,只有以上三点都一样的情况下才允许访问相同的cookie、localStorage和发送Ajax请求,以上一点不

    2024年02月14日
    浏览(36)
  • ERR_UNSAFE_PORT浏览器安全问题导致无法访问的解决方案

    配置好web的https协议的服务器后,使用浏览器访问服务器的时候出现ERR_UNSAFE_PORT无法访问,如下图提示。 img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” / 经过抓取报文分析,并没有抓到访问服务器的报文,定位发现是浏览器的保护机制自动拦截了请求,和

    2024年02月03日
    浏览(97)
  • 在uniapp Vue3版本中如何解决web/H5网页浏览器跨域的问题

    uniapp项目在浏览器运行,有可能调用某些接口会出现跨域问题,报错如下图所示: 存在跨域问题的原因是因为浏览器的同源策略,也就是说前端无法直接发起跨域请求。同源策略是一个基础的安全策略,但是这也会给uniapp/Vue开发者在部署时带来一定的麻烦。一般来说,浏览

    2024年01月21日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包