欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中解決跨域問題的方法匯總(建議收藏)

 更新時間:2024年04月02日 17:07:16   作者:逆流°只是風(fēng)景-bjhxcc  
我們在開發(fā)過程中經(jīng)常會遇到前后端分離而導(dǎo)致的跨域問題,導(dǎo)致無法獲取返回結(jié)果,下面給大家介紹Java中解決跨域問題的方法匯總,感興趣的朋友跟隨小編一起看看吧

背景

我們在開發(fā)過程中經(jīng)常會遇到前后端分離而導(dǎo)致的跨域問題,導(dǎo)致無法獲取返回結(jié)果??缬蚓拖穹蛛x前端和后端的一道鴻溝,君在這邊,她在那邊,兩兩不能往來.

一、什么是跨域?為什么會出現(xiàn)跨域

  • 定義
    • 跨域(CORS)是指不同域名之間相互訪問??缬?,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略所造成的,是瀏覽器對于JavaScript所定義的安全限制策略。
    • 當(dāng)一個請求url的協(xié)議、域名、端口三者之間任意一個與當(dāng)前頁面url不同即為跨域。
  • 原因
    • 在前后端分離的模式下,前后端的域名是不一致的,此時就會發(fā)生跨域訪問問題。在請求的過程中我們要想回去數(shù)據(jù)一般都是post/get請求,所以…跨域問題出現(xiàn)。
    • 跨域問題來源于JavaScript的同源策略,即只有 協(xié)議+主機名+端口號(如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源??缬騿栴}是針對JS和ajax的,html本身沒有跨域問題,比如a標(biāo)簽、script標(biāo)簽、甚至form標(biāo)簽(可以直接跨域發(fā)送數(shù)據(jù)并接收數(shù)據(jù))等
  • 什么情況會跨域
    • 同一協(xié)議, 如http或https同一IP地址, 如127.0.0.1同一端口, 如8080
    • 以上三個條件中有一個條件不同就會產(chǎn)生跨域問題。

二、Java實現(xiàn)跨域方式

2.1、返回新的 CorsFilter(全局跨域)

package org.chuancey.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;
@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        // 放行哪些原始域
        config.addAllowedOrigin("*");
        // 是否發(fā)送 Cookie
        config.setAllowCredentials(true);
        // 放行哪些請求方式
        config.addAllowedMethod("*");
        // 放行哪些原始請求頭部信息
        config.addAllowedHeader("*");
        // 暴露哪些頭部信息
        config.addExposedHeader("*");
        //2. 添加映射路徑
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**",config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }
}

2.2、重寫 WebMvcConfigurer(全局跨域)

package org.chuancey.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //放行哪些原始域
                .allowedOrigins("*")
                .allowedHeaders("*")
                // 是否發(fā)送Cookie
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "OPTIONS", "DELETE", "PUT", "PATCH")
                .maxAge(3600);
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

2.3、使用注解 (局部跨域)

在控制器(類上)上使用注解 @CrossOrigin,表示該類的所有方法允許跨域。

@RestController
@CrossOrigin(origins = "*")
public class VerificationController {
}

在方法上使用注解 @CrossOrigin

@PostMapping("/check/phone")
    @CrossOrigin(origins = "*")
    public boolean checkPhoneNumber(@RequestBody @ApiParam VerificationPojo verification) throws BusinessException {
        return false;
    }

2.4、手動設(shè)置響應(yīng)頭(局部跨域)

使用 HttpServletResponse 對象添加響應(yīng)頭(Access-Control-Allow-Origin)來授權(quán)原始域,這里 Origin的值也可以設(shè)置為 “*”,表示全部放行。

@RequestMapping("/home")
public String home(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "home";
}

2.5、使用自定義filter實現(xiàn)跨域

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Slf4j
@Configuration
@WebFilter(filterName = "accessFilter", urlPatterns = "/*")
public class MyCorsFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
    chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {log.info("AccessFilter過濾器初始化!");}
  public void destroy() {}
}

xml使自定義Filter生效方式

<!-- 跨域訪問 START-->
<filter>
 <filter-name>CorsFilter</filter-name>
 <filter-class>org.chuancey.filter.MyCorsFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>CorsFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 跨域訪問 END  -->

2.6、Spring Cloud Gateway 跨域配置

spring: 
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            # 允許跨域的源(網(wǎng)站域名/ip),設(shè)置*為全部
            # 允許跨域請求里的head字段,設(shè)置*為全部
            # 允許跨域的method, 默認(rèn)為GET和OPTIONS,設(shè)置*為全部
            allow-credentials: true
            allowed-origins:
              - "http://xb.abc.com"
              - "http://sf.xx.com"
            allowed-headers: "*"
            allowed-methods:
              - OPTIONS
              - GET
              - POST
              - DELETE
              - PUT
              - PATCH
            max-age: 3600

注意: 通過gateway 轉(zhuǎn)發(fā)的其他項目,不要進行配置跨域配置

有時即使配置了也不會起作用,這時你可以根據(jù)瀏覽器控制的錯誤輸出來查看問題,如果提示是 response 中 header 出現(xiàn)了重復(fù)的 Access-Control-* 請求頭,可以進行如下操作

import java.util.ArrayList;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component("corsResponseHeaderFilter")
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
  @Override
  public int getOrder() {
    // 指定此過濾器位于NettyWriteResponseFilter之后
    // 即待處理完響應(yīng)體后接著處理響應(yīng)頭
    return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
  }
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    return chain.filter(exchange).then(Mono.defer(() -> {
      exchange.getResponse().getHeaders().entrySet().stream()
          .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
          .filter(kv -> (
              kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
                  || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
                  || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)
                  || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)
                  || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_MAX_AGE)))
          .forEach(kv -> {
            kv.setValue(new ArrayList<String>() {{
              add(kv.getValue().get(0));
            }});
          });
      return chain.filter(exchange);
    }));
  }
}

2.7、使用Nginx配置

location / {
   add_header Access-Control-Allow-Origin *;
   add_header Access-Control-Allow-Headers X-Requested-With;
   add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
   if ($request_method = 'OPTIONS') {
     return 204;
   }
}

2.8、繼承 HandlerInterceptorAdapter

@Component
public class CrossInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
    }
}

到此這篇關(guān)于Java中解決跨域問題的幾種方法的文章就介紹到這了,更多相關(guān)Java跨域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java?IO與NIO高效的輸入輸出操作深入探究

    Java?IO與NIO高效的輸入輸出操作深入探究

    這篇文章主要為大家介紹了Java?IO與NIO高效的輸入輸出操作深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Spring 異常單元測試的解決

    Spring 異常單元測試的解決

    這篇文章主要介紹了Spring 異常單元測試的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 利用spring boot如何快速啟動一個web項目詳解

    利用spring boot如何快速啟動一個web項目詳解

    這篇文章主要給大家介紹了關(guān)于利用spring boot如何快速啟動一個web項目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧、
    2017-12-12
  • SpringBoot使用YML文件進行多環(huán)境配置的三種方法

    SpringBoot使用YML文件進行多環(huán)境配置的三種方法

    SpringBoot通過其靈活的配置機制,使得在不同環(huán)境中管理應(yīng)用設(shè)置變得簡單,尤其是使用YAML文件進行配置,它提供了一種簡潔、易讀的方式來定義應(yīng)用的配置,本文將探討在SpringBoot中使用YAML文件進行多環(huán)境配置的三種方法,需要的朋友可以參考下
    2024-04-04
  • ThreadLocal導(dǎo)致JVM內(nèi)存泄漏原因探究

    ThreadLocal導(dǎo)致JVM內(nèi)存泄漏原因探究

    ThreadLocal是JDK提供的線程本地變量機制,但若使用不當(dāng)可能導(dǎo)致內(nèi)存泄漏。正確的使用方式是在使用完后及時remove,或者使用弱引用等手段避免強引用導(dǎo)致的內(nèi)存泄漏。在多線程編程中,合理使用ThreadLocal可以提高并發(fā)性能,但也需要注意其潛在的內(nèi)存泄漏問題
    2023-04-04
  • Java虛擬機內(nèi)存結(jié)構(gòu)及編碼實戰(zhàn)分享

    Java虛擬機內(nèi)存結(jié)構(gòu)及編碼實戰(zhàn)分享

    這篇文章主要介紹了Java虛擬機內(nèi)存結(jié)構(gòu)及編碼實戰(zhàn)分享,文章圍繞詳細(xì)主題展開相關(guān)資料具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04
  • Java壓縮和解壓縮ZIP文件實戰(zhàn)案例

    Java壓縮和解壓縮ZIP文件實戰(zhàn)案例

    這篇文章主要給大家介紹了關(guān)于Java壓縮和解壓縮ZIP文件的相關(guān)資料,ZIP是一種較為常見的壓縮形式,最近項目中遇到了再Java中壓縮和解壓縮zip文件的需求,特此分享給大家,需要的朋友可以參考下
    2023-07-07
  • 解析Mybatis判斷表達式源碼分析

    解析Mybatis判斷表達式源碼分析

    這篇文章主要介紹了Mybatis判斷表達式源碼分析,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解

    IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解

    這篇文章主要介紹了IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Mybatis-Plus中updateById方法不能更新空值問題解決

    Mybatis-Plus中updateById方法不能更新空值問題解決

    本文主要介紹了Mybatis-Plus中updateById方法不能更新空值問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評論