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

學無先后,達者為師

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

Spring mvc解決跨域請求:Response to preflight request doesn‘t pass access control check

作者:heroleader 更新時間: 2022-03-14 編程語言

在nginx跨域請求cors配置如下:

location / {
        add_header         'Access-Control-Allow-Origin' 'https://api.xxxx.com';
        add_header         "Access-Control-Allow-Credentials" "true";
        add_header         "Access-Control-Allow-Headers" "x-requested-with,content-type";
        proxy_pass         http://localhost:8080;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

主要是添加了三個用于控制CORS的頭信息:

  • Access-Control-Allow-Origin:允許的來源
  • Access-Control-Allow-Credentials:設置為true,允許ajax異步請求帶cookie信息
  • Access-Control-Allow-Headers:設置為x-requested-with,content-type,允許ajax余部請求。

這個配置也可以在spring mvc里配置。

問題:

配置好后,異步跨域請求成功。

當發(fā)起post請求,請求的數(shù)據(jù)是放在request body里,請求的Content-Type為application/json。Spring MVC需要使用@RequestBody來接收數(shù)據(jù)。

這是一次非簡單的請求,瀏覽器會發(fā)起一次Options的預請求。發(fā)起Options請求報403錯誤:

Failed to load https://api.xxxx.com/auth.json: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://other.xxxx.com' is therefore not allowed access. The response had HTTP status code 403.

?

解決方法

原以為是自己的配置有誤,但找了很多資料可以確定配置是沒有問題。后來debug跟蹤Spring MVC DispatcherServlet的調用,發(fā)現(xiàn)在DispacerServlet是因為沒有找都到執(zhí)行Options請求的方法。

在做跨域請求時,配置好CORS相關頭信息后,以為就可以了,這很容易忽略在Spring MVC添加對Options請求的處理。

解決方法有兩種:

  • 在攔截器統(tǒng)一添加對Options請求的支持
  • 添加一個支持Options的ReqeuestMapping。

攔截器示例:

public class CrosDomainAllowInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            response.setStatus(HttpStatus.OK.value());
            return false;
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
    }
}

@RequestMapping示例

@RequestMapping(value = "/*",method = RequestMethod.OPTIONS)
public ResponseEntity handleOptions(){
    return ResponseEntity.noContent();
}

原文鏈接:https://blog.csdn.net/baoyinwang/article/details/110955167

欄目分類
最近更新