在 React POST 之前禁用 OPTIONS 请求

Disable OPTIONS request before POST in React

我有一个基于 Typescript 的 React 应用程序,它托管在我的 PC 上。 我使用 Spring 网关将请求转发到另一个微服务。 GET 请求工作正常,但对于 POST 请求,我得到:

Access to XMLHttpRequest at 'http://1.1.1.1:8080/api/support/tickets/create' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我遇到了这个 Spring 云网关问题:https://github.com/spring-cloud/spring-cloud-gateway/issues/229

Spring云配置:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder, LoggingGatewayFilterFactory loggingFactory) {
    return builder.routes()
            .route("route_id",
                    route -> route
                            .path("/api/support/tickets/**")
                            .filters(f -> f.rewritePath("/api/support/tickets/(?<RID>.*)", "/support/tickets/${RID}"))
                            .uri("lb://merchant-hub-admin-service")
            )
            .build();
}

反应代码:

export async function getTicket(id: string) {
  return await axios.get(`${baseUrl}/support/tickets/ticket/${id}`);
}

export async function postTicket(
  data: TicketFullDTO
): Promise<AxiosResponse<TicketFullDTO>> {
  return await axios.post<TicketFullDTO>(
    `${baseUrl}/support/tickets/create`, data);
}

这是由于买入Spring云网关:https://github.com/spring-cloud/spring-cloud-gateway/issues/2472

我尝试实施此解决方法:

@Bean
public RoutePredicateHandlerMapping tusRoutePredicateHandlerMapping(FilteringWebHandler webHandler,
                                                                    RouteLocator routeLocator,
                                                                    GlobalCorsProperties globalCorsProperties,
                                                                    Environment environment) {
    RoutePredicateHandlerMapping routePredicateHandlerMapping = new RoutePredicateHandlerMapping(webHandler,
            routeLocator, globalCorsProperties, environment);
    routePredicateHandlerMapping.setCorsProcessor(new CrackCorsProcessor());
    return routePredicateHandlerMapping;
}
import org.springframework.lang.Nullable;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.DefaultCorsProcessor;
import org.springframework.web.server.ServerWebExchange;

public class CrackCorsProcessor extends DefaultCorsProcessor {
    @Override
    public boolean process(@Nullable CorsConfiguration config, ServerWebExchange exchange) {
        return false;
    }
}

但它不起作用。你知道我怎么解决这个问题吗?

看来你的问题只是关于本地开发的。

Create React 应用程序通过支持开发服务器作为您的 API 端点的代理来精确解决这个问题。

只需在 package.json 中的 proxy 键中添加 API 域。有关此内容的更多信息 here

对于生产,您应该将它们都托管在同一域下(使用反向代理路由静态内容与基于 URL 路径的 api 请求),或者找到一个永久的 cors 友好您后端的解决方案。

Cors 是一项浏览器功能,无法禁用。虽然,当不使用 POST 方法时,您可以绕过预检,但如果没有正确的 headers set

,您仍然无法访问响应 body

实际上,CORS 是一种浏览器功能,您可以在开发 区域禁用它。

当这两个不匹配时,浏览器应该调用 non-matched URLs(网站 URL & API URL)的选项,浏览器必须向后端 API 调用 OPTIONS 调用才能继续,对于生产 如果您的网站 URL 和 API 不匹配 应该让您的后端或 DevOps 人员解决它,但对于开发领域,您可以做几件事:

  • 如果您正在使用 CRA, 可以帮助您。

  • 如果您正在使用自定义配置并且您有一个 Webpack 配置文件,请将此行添加到您的 Webpack,它可以帮助您:

    module.exports = {
      devServer: {
        proxy: 'http://1.1.1.1:8080',
      },
    
  • 另一种可爱的方法是直接在 Chrome 中禁用安全性以便于开发,将这些命令放在它们相关的 OS 和 运行 中,你会运行 没有安全性的 chrome 的新实例(没有 OPTIONS 调用):

    ## macOS
    open -na Google\ Chrome --args --user-data-dir=/tmp/temporary-chrome-profile-dir --disable-web-security --disable-site-isolation-trials
    
    ## windows
    chrome.exe --disable-web-security
    
    ## linux
    google-chrome --disable-web-security
    

关于最后一项的更多信息,您可以阅读this post