日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

SpringBoot工具庫(kù):解決SpringBoot2.*版本跨域問題

作者:月半花開 更新時(shí)間: 2024-03-24 編程語言

1.解決問題:When allowCredentials is true, xxxxxxx , using “allowedOriginPatterns“ instead

2.3版本跨域配置如下

/**
 * 跨域問題解決
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

1.1.解決方法:

????????Spring官網(wǎng)有類似問題:https://github.com/spring-projects/spring-framework/issues/26111

????????大致意思為:提供了allowedOriginPatterns方法供使用。原本的allowCredentials為true時(shí),allowedOrigins不能使用 * 號(hào)匹配

/**
 * 跨域問題解決
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

其實(shí)解決跨域大分類有2種方式,一種是利用注解,一種寫個(gè)配置類?

2.解決跨域的幾種方式

2.1.CorsFilter 方式設(shè)置跨域

????????CorsFilter過濾器:通過Spring Boot的CORS過濾器來處理跨域請(qǐng)求,需要定義一個(gè)CorsFilter Bean,例如:

@Configuration
public class CoreFilter {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");  // 不是 addAllowedOrigin
        config.setAllowCredentials(true);
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return new CorsFilter(source);
    }
}

2.2.攔截器實(shí)現(xiàn)跨域

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.Serializable;

@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer, Serializable {
    private static final long serialVersionUID = 1L;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 不是 addAllowedOrigin
                .allowedOriginPatterns("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(3600)
                .allowCredentials(true);
    }

    /**
     * 修改訪問路徑
     * @param configurer
     */
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // 設(shè)置為true后,訪問路徑后加/ 也能正常訪問  /user == /user/
         configurer.setUseTrailingSlashMatch(true);
    }

}

????????與使用 CorsFilter 方式一樣,當(dāng) allowCredentials 為 true時(shí),不可以將 allowedOrigins 設(shè)置為 *,必須用 allowedOriginPatterns。否則最終也會(huì)到 CorsConfiguration#validateAllowCredentials 方法中的校驗(yàn)。

2.3.通過 @CrossOrigin 實(shí)現(xiàn)跨域

@CrossOrigin 可以標(biāo)注類和單個(gè)方法。使用@CrossOrigin注解標(biāo)注在Controller類或方法上,指定允許跨域的源地址、請(qǐng)求方法、Header等屬性

標(biāo)注類:

該 Controller 請(qǐng)求路徑下的所有方法都允許跨域。

@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping(method = RequestMethod.GET, path = "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

????????在類級(jí)別上添加了?@CrossOrigin。因此,retrieve()?和?remove()?方法都啟用了?@CrossOrigin。我們可以通過指定以下注解屬性的值來自定義配置:originsmethodsallowedHeadersexposedHeadersallowCredentials?或?maxAge

標(biāo)注方法:

僅標(biāo)注的方法允許跨域。

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, path = "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

在上面的示例中,我們只為?retrieve()?方法啟用了 CORS。我們可以看到,我們沒有為?@CrossOrigin?注解設(shè)置任何配置,因此它使用的是默認(rèn)值:

  • 允許所有 origin。
  • 允許使用的 HTTP 方法是?@RequestMapping?注解(本例中為?GET)中指定的方法。
  • 緩存預(yù)檢響應(yīng)的時(shí)間(maxAge)為 30 分鐘。
在類上和方法上
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://example.com")
    @RequestMapping(method = RequestMethod.GET, "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Spring 將合并兩個(gè)注解的屬性,創(chuàng)建合并的 CORS 配置。

這里,兩個(gè)方法的?maxAge?都是?3600?秒,remove()?方法允許所有 origin,而?retrieve()?方法只允許來自?http://example.com?的 origin。

2.4.nginx

Nginx反向代理:將請(qǐng)求轉(zhuǎn)發(fā)給Nginx,由Nginx統(tǒng)一處理跨域請(qǐng)求,例如:

location /api/ {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }
    proxy_pass http://localhost:8080;
}

2.5.webFilter

使用@WebFilter注解:該注解可以直接在過濾器類上使用,并指定過濾的url,類似于xml文件中配置的filter

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
@WebFilter(urlPatterns = "/*")
@Order(-99999)
public class CorsFilter extends HttpFilter {

	private static final long serialVersionUID = 2386571986045107652L;

	private static final String OPTIONS_METHOD = "OPTIONS";

	@Override
	protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {

		String origin = req.getHeader(HttpHeaders.ORIGIN);

		if (!StringUtils.isEmpty(origin)) {
			
			// 允許客戶端的域
			res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);

			// 允許客戶端提交的Header
			String requestHeaders = req.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
			if (!StringUtils.isEmpty(requestHeaders)) {
				res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);
			}
			
			// 允許客戶端訪問的Header
			res.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
			
			// 允許客戶端攜帶憑證信息
			res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
			
			// 允許客戶端請(qǐng)求方法
			res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, OPTIONS, DELETE");

			if (OPTIONS_METHOD.equalsIgnoreCase(req.getMethod())) {
				res.setStatus(HttpServletResponse.SC_NO_CONTENT);
				res.setContentType(MediaType.TEXT_HTML_VALUE);
				res.setCharacterEncoding("utf-8");
				res.setContentLength(0);
				res.addHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800");
				return;
			}
		}

		super.doFilter(req, res, chain);
	}
}

原文鏈接:https://blog.csdn.net/qq_20957669/article/details/132616061

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新