web跨域问题

跨域问题

Ajax常用解决方法
  1. 使用@CrossOrigin注解

    1. 最简单的,覆盖最广的方法
    2. 使用方法:在controller类上或controller类中方法上添加注解即可
    3. 参数:https://zhuanlan.zhihu.com/p/66789473
      1. 基本参数:
        • origins : 允许可访问的域列表,匹配的域名是跨域预请求 Response 头中的 ‘Access-Control-Aloow_origin’ 字段值。不设置确切值时默认支持所有域名跨域访问。
        • **maxAge ** : 准备响应前的缓存持续的最大时间(以秒为单位),对应的是是跨域请求 Response 头中的 ‘Access-Control-Max-Age’ 字段值,表示预检请求响应的缓存持续的最大时间,目的是减少浏览器预检请求/响应交互的数量。默认值1800s。设置了该值后,浏览器将在设置值的时间段内对该跨域请求不再发起预请求。
      2. 其他参数:
        1. allowedHeaders: 跨域请求中允许的请求头中的字段类型, 该值对应跨域预请求 Response 头中的 ‘Access-Control-Allow-Headers’ 字段值。 不设置确切值默认支持所有的header字段(Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma)跨域访问。
        2. exposedHeaders: 跨域请求请求头中允许携带的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma这六个基本字段之外的其他字段信息,对应的是跨域请求 Response 头中的 'Access-control-Expose-Headers’字段值。
        3. methods: 跨域HTTP请求中支持的HTTP请求类型(GET、POST…),不指定确切值时默认与 Controller 方法中的 methods 字段保持一致。
        4. allowCredentials: 该值对应的是是跨域请求 Response 头中的 ‘Access-Control-Allow-Credentials’ 字段值。浏览器是否将本域名下的 cookie 信息携带至跨域服务器中。默认携带至跨域服务器中,但要实现 cookie 共享还需要前端在 AJAX 请求中打开 withCredentials 属性。
    4. 要求
      1. springMVC的版本要在4.2或以上版本才支持
      2. JDK版本在java 7 version (7u80)以上才支持,否则会编译报错:
        1. https://stackoverflow.com/questions/45656877/crossorigin-annotation-doesnt-compile
        2. https://segmentfault.com/a/1190000037698301
    5. 源码讲解:https://zhuanlan.zhihu.com/p/66789473
  2. jsonp

    1. 使用较多,但缺陷明显的方法,不推荐

    2. 使用方法

      1. 最简单应用:前端:ajax请求中dataType属性改为jsonp,type属性改为get

      2. 后端:

        1. 接收参数中多一个String类型的callback参数(SpringMVC直接在方法参数中添加该参数即可,servlet则 getParameter()方法获取即可)

        2. 将返回数据进行jsonp处理(可选两种方式):

          1. SpringMVC的@RequestMapping()注解指定 produces = {“application/javascript;charset=UTF-8”},再数据与上述callback参数进行以下方式的拼接

            {result}=callback +"(" {result} ")";
            

            (servlet直接进行拼接OutputStream流返回即可)

          2. 该方式只支持SpringMVC4.2版本以上:将数据进行以下处理即可

            MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
            mappingJacksonValue.setJsonpFunction(callback);
            return mappingJacksonValue;
            
    3. 其他参数:(ajax中可配置的参数)

      1. jsonp :(默认:“callback”): JSONP回调查询参数的名称
        1. 若修改,后端中参数名称也要对应修改
      2. jsonpCallback (默认: “jsonp{N}”): 全局JSONP回调函数的 字符串(或返回的一个函数)名。设置该项能启用浏览器的缓存
      3. cache (默认: true): 浏览器是否应该被允许缓存GET响应。从v1.1.4开始,当dataType选项为"script"jsonp时,默认为false
    4. 缺陷

      1. 只能发送 GET 请求,无法发送其他类型的请求
      2. ajax中无法携带自定义请求头,否则会报400的状态码,而且该请求不会发送至目标服务器就直接返回400状态码
        1. https://stackoverflow.com/questions/59596369/jquery-ajax-jsonp-returns-400-bad-request#
  3. WebMvcConfigurerAdapter配置类

    1. 作用范围与@CrossOrigin注解相同,但配置方法相对更复杂一些

    2. 使用方法:在spring项目中新建一个配置类即可,如下

      @Configuration
      @EnableWebMvc
      public class CorsConfig extends WebMvcConfigurerAdapter {
          @Override
          public void addCorsMappings(CorsRegistry corsRegistry){
              /**
               * 所有请求都允许跨域,使用这种配置就不需要
               * 在interceptor中配置header了
               */
              corsRegistry.addMapping("/**")
                      .allowCredentials(true)
                      .allowedOrigins("*")
                      .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                      .allowedHeaders("*")
                      .maxAge(3600);
          }
      }
      
      • Spring Boot项目的话使用以下代码

        @SpringBootConfiguration
        public class CorsConfig implements WebMvcConfigurer {
        
            @Override
            public void addCorsMappings(CorsRegistry corsRegistry){
                /**
                 * 所有请求都允许跨域,使用这种配置就不需要
                 * 在interceptor中配置header了
                 */
                corsRegistry.addMapping("/**")
                        .allowCredentials(true)
                        .allowedOrigins("*")
                        .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                        .allowedHeaders("*")
                        .maxAge(3600);
            }
        }
        
  4. JSONP与其他两种方式的比较

    1. CORS与JSONP的使用目的相同,但是比JSONP更强大。
    2. JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
其他跨域问题解决方法
  1. 基于filter的跨域实现

    1. 该方式也是ajax请求跨域的一种处理方法,但较为复杂

    2. 使用方法:(找到三种实现,具体用哪个没有验证)

      1. SpringBoot

        @Configuration
        public class MyConfiguration {
         
            @Bean
            public FilterRegistrationBean corsFilter() {
                UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                CorsConfiguration config = new CorsConfiguration();
                config.setAllowCredentials(true);
                config.addAllowedOrigin("*");
                config.addAllowedHeader("*");
                config.addAllowedMethod("*");
                source.registerCorsConfiguration("/**", config);
                FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
                bean.setOrder(0);
                return bean;
            }
        }
        
      2. SpringMVC

        @Configuration
        public class HttpFilterConfig {
        
            @Bean
            public FilterRegistrationBean<CorsFilter> corsFilter() {
                CorsConfiguration corsConfig = new CorsConfiguration();
                corsConfig.setAllowCredentials(true);
                corsConfig.addAllowedOrigin(CorsConfiguration.ALL);
                corsConfig.addAllowedMethod(CorsConfiguration.ALL);
                corsConfig.addAllowedHeader(CorsConfiguration.ALL);
                //默认可不设置这个暴露的头。这个为了安全问题,不能使用*。设置成*,后面会报错:throw new IllegalArgumentException("'*' is not a valid exposed header value");
                //corsConfig.addExposedHeader("");
                corsConfig.setMaxAge(3600L);
                
                UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
                configSource.registerCorsConfiguration("/**", corsConfig);
                
                FilterRegistrationBean<CorsFilter> corsBean = new FilterRegistrationBean<CorsFilter>(new CorsFilter(configSource));
                corsBean.setName("crossOriginFilter");
                corsBean.setOrder(0);//这个顺序也有可能会有影响,尽量设置在拦截器前面
                return corsBean;
            }
        }
        
      3. 未知

        @Configuration
        public class CorsConfig{
        	 private CorsConfiguration buildConfig() {
        	        CorsConfiguration corsConfiguration = new CorsConfiguration();
        	        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        	        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        	        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        	        return corsConfiguration;
        	    }
        
        	    @Bean
        	    public CorsFilter corsFilter() {
        	        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        	        source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
        	        return new CorsFilter(source);
        	    }
        }
        
  2. XML命名空间

    1. 该方式也是ajax请求跨域的一种处理方法,但需要新建一个SpringMVC的xml文件,SpringBoot如何配置未知

    2. 使用方法

      1. 简单配置

        <mvc:cors>
            <mvc:mapping path="/**" />
        </mvc:cors>
        
      2. 复杂配置

        <mvc:cors>
        
            <mvc:mapping path="/**"
                allowed-origins="*"
                allowed-methods="'POST', 'GET', 'PUT', 'OPTIONS', 'DELETE'"
                allowed-headers="*"
                exposed-headers="*" 
                allow-credentials="false"
                max-age="3600" />
        
        </mvc:cors>
        

iframe与主站资源跨域问题解决:

  1. 见我之前的文章:https://blog.csdn.net/qq_43175022/article/details/120024663
  2. https://segmentfault.com/a/1190000011145364
  3. https://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 要解决Web API的跨域问题,可以通过在Web.Config中的system.webServer节点下增加跨域配置来实现。具体的配置如下所示: ``` <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="AuthToken, Authorization, Origin, Content-Type, Accept, X-Requested-With" /> <add name="Access-Control-Allow-Methods" value="GET,HEAD,POST,OPTIONS" /> </customHeaders> </httpProtocol> </system.webServer> ``` 另外,还可以在代码中使用EnableCorsAttribute来启用跨域请求。例如,在EnableCrossSiteRequest方法中添加以下代码: ``` private static void EnableCrossSiteRequest(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*" ); config.EnableCors(cors); } ``` 这样就可以解决Web API的跨域问题了。\[1\]\[2\] #### 引用[.reference_title] - *1* [ASP.NET WebAPI解决跨域问题](https://blog.csdn.net/hbzhlt/article/details/122221683)[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^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [关于 Asp.Net Web Api 跨域问题解决方案](https://blog.csdn.net/squallonline8708/article/details/122728285)[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^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值