程序员的资源宝库

网站首页 > gitee 正文

解决跨域问题

sanyeah 2024-04-13 16:15:49 gitee 4 ℃ 0 评论

CORS全称Cross-Origin Resource Sharing,意为跨域资源共享。当一个资源去访问另一个不同域名或者同域名不同端口的资源时,就会发出跨域请求。如果此时另一个资源不允许其进行跨域资源访问,那么访问的那个资源就会遇到跨域问题。
跨域问题演示及解决
时前端代码运行在8090端口上,后端代码运行在8080端口上,由于其域名都是localhost,但是前端和后端运行端口不一致,此时前端访问后端接口时,就会产生跨域问题。
覆盖默认的CorsFilter来解决该问题
添加GlobalCorsConfig配置文件来允许跨域访问。

处理方法:config配置允许跨域调用的过滤器

点击查看代码
package com.macro.mall.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;

/**
 * 全局跨域配置
 * Created by macro on 2019/7/27.
 */
@Configuration
public class GlobalCorsConfig {

    /**
     * 允许跨域调用的过滤器
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOrigin("*");
        //允许跨越发送cookie
        config.setAllowCredentials(true);
        //放行全部原始头信息
        config.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

重新运行代码,点击登录按钮

发现需要登录认证的/admin/info接口的OPTIONS请求无法通过认证,那是因为复杂的跨越请求需要先进行一次OPTIONS请求进行预检,我们的应用整合了SpringSecurity,对OPTIONS请求并没有放开登录认证。

设置SpringSecurity允许OPTIONS请求访问

在SecurityConfig类的configure(HttpSecurity httpSecurity)方法中添加如下代码。

.antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求

.permitAll()

解决跨域问题的三种思路

1、客户端浏览器解除跨域限制(理论上可以但是不现实)
2、发送JSONP请求替代XHR请求(并不能适用所有的请求方式,不推荐)
3、修改服务器端(包括HTTP服务器和应用服务器)(推荐)
.补充知识
在HTTP1.1 协议中的,请求方法分为GET、POST、PUT、DELETE、HEAD、TRACE、OPTIONS、CONNECT 八种。浏览器根据这些请求方法和请求类型将请求划分为简单请求和非简单请求。

简单请求:浏览器先发送(执行)请求然后再判断是否跨域。

请求方法为 GET、POST、HEAD,请求头header中无自定义的请求头信息,请求类型Content-Type 为 text/plain、multipart/form-data、application/x-www-form-urlencoded 的请求都是简单请求。

非简单请求:浏览器先发送预检命令(OPTIONS方法),检查通过后才发送真正的数据请求。

预检命令会发送自定义头为Access-Control-Request-Headers: content-type的请求到服务器,根据响应头的中的 “Access-Control-Allow-Headers”: “Content-Type” 判断服务器是否允许跨域访问。预检命令是可以缓存,服务器端设置 “Access-Control-Max-Age”: “3600”,这样后面发送同样的跨域请求就不需要先发送预检命令了

3.修改服务器端

根据现如今网站架构设计,可以将前端应用看作调用方使用服务,将后端应用看作被调用方提供服务。

在应用服务器增加指定字段

对于不带 Cookie 的跨域请求,设置允许跨域的原始域名为任意域名,“Access-Control-Allow-Origin”: “”,设置允许跨域的方法为任意方法,“Access-Control-Allow-Methods”: “”,但是这样的星号设置不能满足带 Cookie 的跨域请求。

在 Java Web 中,可以添加一个过滤器来设置上面的参数。springboot使用注解完成

在 HTTP 服务器增加指定字段

以常用的 Nginx 服务器和 Apache 服务器为例。
Nginx 服务器允许跨域配置(注意不要手动直接点击Nginx.exe,否则停止和重新载入配置会失败的)

调用方修改
调用方的解决思路是反向代理,也即是将被调用方的域名代理到调用方域名下,这样就符合同源策略了,也就解决了跨域问题。

具体解决方法:

从8001访问88,引发CORS跨域请求,浏览器会拒绝跨域请求
跨域
问题描述:已拦截跨源请求:同源策略禁止读取位于 http://localhost:88/api/sys/login 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。

问题分析:这是一种跨域问题。访问的域名和端口和原来的请求不同,请求就会被限制

跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对js施加的安全限制。(ajax可以)

同源策略:是指协议,域名,端囗都要相同,其中有一个不同都会产生跨域;

在这里插入图片描述

跨域流程:

这个跨域请求的实现是通过预检请求实现的,先发送一个OPSTIONS探路,收到响应允许跨域后再发送真实请求

在这里插入图片描述

前面跨域的解决方案:

方法1:设置nginx包含admin和gateway
方法2:让服务器告诉预检请求能跨域

在这里插入图片描述

在这里插入图片描述

解决方法:在网关中定义“GulimallCorsConfiguration”类,该类用来做过滤,允许所有的请求跨域。
package com.yxj.gulimall.gateway.config;

@Configuration // gateway
public class GulimallCorsConfiguration {

    @Bean // 添加过滤器
    public CorsWebFilter corsWebFilter(){
        // 基于url跨域,选择reactive包下的
        UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
        // 跨域配置信息
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 允许跨域的头
        corsConfiguration.addAllowedHeader("*");
        // 允许跨域的请求方式
        corsConfiguration.addAllowedMethod("*");
        // 允许跨域的请求来源
        corsConfiguration.addAllowedOrigin("*");
        // 是否允许携带cookie跨域
        corsConfiguration.setAllowCredentials(true);
        
       // 任意url都要进行跨域配置
        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}

再次访问:http://localhost:8001/#/login

在这里插入图片描述

错误原因是,子项目中也配置了拦截跨域请求:
http://localhost:8001/renren已拦截跨源请求:同源策略禁止读取位于 http://localhost:88/api/sys/login 的远程资源。(原因:不允许有多个 ‘Access-Control-Allow-Origin’ CORS 头)n-fast/captcha.jpg?uuid=69c79f02-d15b-478a-8465-a07fd09001e6

出现了多个请求,并且也存在多个跨源请求。为了解决这个问题,注释掉“io.renren.config.CorsConfig”类。然后再次进行访问。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表