关于浏览器中的跨域问题详解

本文介绍了跨域问题的原理,列举了不同场景下的请求是否涉及跨域,详细解释了CORS、JSONP、代理等解决跨域问题的方法,并提供了CORS预检响应报头的设置示例。
摘要由CSDN通过智能技术生成

首先,什么是跨域?

          跨域问题是指在Web开发中,由于浏览器的同源策略限制,当一个源(origin)尝试通过脚本(如JavaScript中的XMLHttpRequest或Fetch API)访问另一个不同源的资源时,浏览器会阻止这种请求,从而导致数据无法正常获取。这里的“源”由协议、域名和端口号三部分组成,只有完全相同的三个部分才被视为同源。
同源策略是一种安全机制,它用于防止恶意网站通过网页脚本(例如JavaScript)对其他网站的内容进行非法读取或操作

以下为是否需要跨域的几种请求例子

        根据,以上例子,我们可以得出一个快速判断是否需要跨域请求的方法,正如前面提到的‘源’相同,意为协议、域名和端口号三者相同,即可不用执行跨域操作。

        其次,说明一个很容易误解的点,并非所有请求都需要进行跨域,同源策略只影响到那些从网页中发起的、需要和服务器进行交互的请求,特别是通过JavaScript脚发起的Ajax请求。以下类型的请求通常不受同源策略限制:
        普通链接导航:用户直接点击超链接跳转到另一个页面,这种情况下浏览器不会检查是否跨域。
        图片、样式、脚本等资源加载:网页中通过<img>、<link>、<script>等标签引用的图片、CSS样式表和JavaScript文件,可以跨域加载。(例如登陆页面中的验证码图片请求)
        表单提交:HTML表单通过POST方式提交到不同域名下的服务器,虽然服务器接收到请求并能正常响应,但在预请求阶段(如OPTIONS请求)和响应结果处理上,前端JS脚本可能受到同源策略限制,无法访问响应内容。
        iframe嵌入:可以在页面中嵌入来自不同域的iframe,但需要注意的是,由于同源策略,父页面对于iframe中的DOM操作和通信(如通过window.postMessage之外的方式)会受到限制。
总之,只有当一个网页尝试通过JavaScript发起Ajax请求访问不同源的API时,才需要考虑跨域问题。而对于静态资源加载或者页面间的直接跳转,一般无需关心跨域问题。

跨域的请求流程如下

简单说明一下流程就是,网页首先会发送一个预检请求给服务器,请求方式为OPTIONS

当这条请求通过时,才会发送真实的请求。

具体信息可以参考官网的实例文档跨源资源共享(CORS) - HTTP | MDN (mozilla.org)

知道了大概的流程,我们来看看该如何解决跨域问题。

解决跨域问题的几种方式

CORS(Cross-Origin Resource Sharing)
        服务器端允许指定源通过设置响应头来访问资源,例如在HTTP响应中添加Access-Control-Allow-Origin、Access-Control-Allow-Methods等头部信息。
JSONP(JSON with Padding):
一种基于GET请求的跨域解决方案,利用 <script> 标签不受同源策略限制的特点,通过动态插入脚本标签从不同源获取数据。服务端需要支持返回包裹了回调函数名和数据的JSON格式字符串。
代理(Proxying):
        在前端开发环境中使用如webpack的devServer或Vue CLI等提供的proxy功能,将所有跨域请求转发到同一个服务器,然后由该服务器作为中间层向目标服务器发送请求,从而避免浏览器直接发起跨域请求。
Nginx反向代理:
        在生产环境部署时,可以通过Nginx或其他HTTP服务器配置反向代理规则,使得原本的跨域请求经过服务器内部跳转后,对于浏览器而言,看起来像是同源请求。
设置document.domain:
        对于二级域名相同的情况,可以设置主域名相同的两个页面中的document.domain属性为同一主域名,实现跨子域通信。
Window.postMessage API:
        在跨窗口通信场景下,可以利用postMessage方法进行跨域数据交换,尤其适用于iframe间的通信。
WebSocket协议
        WebSocket协议本身支持跨越原策略,但客户端和服务端仍需遵循一些特定约定以确保安全。
CSP(Content Security Policy):
        内容安全策略可以配置允许加载来自特定源的内容,间接地支持跨域请求。
自定义协议或扩展:
        在某些情况下,如本地应用与网页交互,可以采用自定义协议或浏览器扩展的方式绕过同源策略。

在以上多种方式中,我们选取两种方法来解析

本地代理解决跨域问题详解

在笔者之前的文章中,提到过一种解决跨域问题的解决办法,详细请查看文章

vue2中的跨域配置_vue2配置跨域-CSDN博客

        该文章中提到的方法,属于以上几种方法中的本地代理(Local Proxy)方法来解决跨域问题。通过在开发服务器的配置文件中设置proxy选项,将前端应用发起的特定请求(例如以/api开头的请求)转发到实际的目标服务器地址,从而规避了浏览器同源策略的限制,在开发环境下实现跨域访问的功能。

CORS编写预检响应报头解决跨域问题

• 1、添加响应头
• Access-Control-Allow-Origin:支持哪些来源的请求跨域
• Access-Control-Allow-Methods:支持哪些方法跨域
• Access-Control-Allow-Credentials:跨域请求默认不包含cookie,设置为true可以包含
cookie
• Access-Control-Expose-Headers:跨域请求暴露的字段
• CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如
果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
• Access-Control-Max-Age:表明该响应的有效时间为多少秒。在有效时间内,浏览器无
须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果
该首部字段的值超过了最大有效时间,将不会生效。

创建CorsConfig类,实现WebMvcConfigurer接口添加@Configuration标签,写入以下内容

  public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .maxAge(3600);
    }

即可在预检的响应中加入解决跨域问题的报头

代码详解

添加映射规则
registry.addMapping("/**")
   允许的来源
   .allowedOrigins("*")
   允许携带凭证
    .allowCredentials(true)
   允许的方法
    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
   缓存时间
    .maxAge(3600);

再次重新启动后台项目即可解决跨域问题了

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要配置Nginx实现浏览器访问,可以按照以下步骤进行配置: 1. 在Nginx服务器上创建一个目录用于存放访问资源。可以使用命令`mkdir /usr/share/nginx/corsmulti02/`来创建目录。 2. 在创建的目录创建一个index.html文件,并添加内容。可以使用命令`echo '<h1>Corsmulti02</h1>' > /usr/share/nginx/corsmulti02/index.html`来创建文件并添加内容。 3. 在Nginx的配置文件添加访问的配置。可以使用add_header语法来配置响应头,使多个名能够访问资源。例如,可以在配置文件的相应位置使用以下语法进行配置: ``` add_header Access-Control-Allow-Origin "http://localhostsource01.odocker.com"; add_header Access-Control-Allow-Origin "http://source02.odocker.com"; ``` 其,将"http://localhostsource01.odocker.com"和"http://source02.odocker.com"替换为允许访问的名。 通过以上配置,就可以实现浏览器访问Nginx服务器上的资源了。在浏览器访问"http://corsmulti02.linuxds.com/"即可访问Nginx服务器上的资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Nginx配置](https://blog.csdn.net/m0_67391683/article/details/126113742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Nginx访问场景配置和防盗链详解](https://download.csdn.net/download/weixin_38737335/14091819)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值