JAX-RX - 被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Methods 不允许方法 PATCH

Posted

技术标签:

【中文标题】JAX-RX - 被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Methods 不允许方法 PATCH【英文标题】:JAX-RX - Blocked by CORS policy: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response 【发布时间】:2019-04-10 15:21:12 【问题描述】:

我正在使用带有 Jersey 2.1 的 Spring Boot

和 Ionic 开发一个应用程序,我已经尝试了我发现的每一个帖子,但没有一个为我解决这个问题,我得到的错误,包括那些说自己创建 @PATCH 接口注释的帖子。

所以,当我在浏览器上进行PATCH 请求时测试时,我在客户端收到了这个错误:

从源 'http://localhost:8100' 在 '' 处访问 XMLHttpRequest 被 CORS 策略阻止:方法 PATCH 不允许 预检响应中的 Access-Control-Allow-Methods。

我的响应过滤器如下,如果我将PATCH 作为允许的方法并且它在 Postman 上完美运行,我不明白为什么我会得到这个:

过滤器:

@Provider
public final class ResponseFilter implements ContainerResponseFilter 

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException 
        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.putSingle("Accept-Patch", "*");
        headers.putSingle("Access-Control-Allow-Origin", "*");
        headers.putSingle("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE, PATCH");
        headers.putSingle("Access-Control-Allow-Credentials", "true");
        headers.putSingle("Access-Control-Max-Age", "3600");
        headers.putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
    

使用PATCH的方法:

import javax.ws.rs.PATCH;


@PATCH
    @Path("/username")
@Produces(MediaType.APPLICATION_JSON)
    public Response actualizarPassword(@Valid @NotNull(message = "user must not be null") final UserDTO userDTO,
                                      @PathParam("username") final String username,
                                      @QueryParam("codigo") @NotNull(message = "codigo musnt be null") final String codigo) 
        userDTO.setUsername(username);
        this.usersService.actualizarPassword(this.userDTOMapper.map(userDTO), codigo);

        return Response.noContent().build();
    

正如我所说,我还尝试使用PATCH 创建注释,正如我在一些答案中所读到的,但是这个 http 方法应该包含在 Jersey 2.1 中,它确实可以在上一篇文章中看到代码,我创建的界面是:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH 

如果我做一个 POSTMAN 请求,这些是我得到的标头:

Accept-Patch →*
Access-Control-Allow-Origin →*
Access-Control-Allow-Methods →POST, PUT, GET, OPTIONS, DELETE, PATCH
Access-Control-Allow-Credentials →true
Access-Control-Max-Age →3600
Access-Control-Allow-Headers →Content-Type, Accept, Authorization
X-Content-Type-Options →nosniff
X-XSS-Protection →1; mode=block
Cache-Control →no-cache, no-store, max-age=0, must-revalidate
Pragma →no-cache
Expires →0
X-Frame-Options →DENY
Content-Type →application/json
Content-Length →54
Date →Wed, 07 Nov 2018 07:46:45 GMT

如果它有某种关联,这是我的 SpringSecurity 配置:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .authorizeRequests().anyRequest().permitAll()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable();
    

    @Override
    public void configure(WebSecurity web ) throws Exception
    
        web.ignoring().antMatchers( HttpMethod.OPTIONS, "/**" );
    

更新 1

我已经打印了响应的代码,我得到了200。但是,我不断收到此错误。

更新 2

根据 sideshowbarker 的要求,我向 POSTMAN 发出了OPTIONS 请求,这是标题:

Allow →HEAD,GET,OPTIONS,PUT,PATCH
Last-modified →Wed, 07 Nov 2018 10:07:57 GMT+01:00
Accept-Patch →*
Access-Control-Allow-Origin →*
Access-Control-Allow-Methods →POST, PUT, GET, OPTIONS, DELETE, PATCH
Access-Control-Allow-Credentials →true
Access-Control-Max-Age →3600
Access-Control-Allow-Headers →Content-Type, Accept, Authorization
Content-Type →application/vnd.sun.wadl+xml
Content-Length →1165
Date →Wed, 07 Nov 2018 09:07:57 GMT

更新 3

我按照建议检查了开发工具中的标题,但 PATCH 方法不存在。为什么是这样?如果我使用 POSTMAN 而不是 Ionic 应用程序,为什么会出现这种情况?

请帮忙,我已经为此苦苦挣扎了好几天...

谢谢

【问题讨论】:

尝试使用 OPTIONS 请求测试 Postman。因为您的浏览器实际上并没有尝试从您的前端代码发出 PATCH 请求。浏览器首先执行 CORS 预检 OPTIONS 请求,但失败了。因此,您需要弄清楚如何配置 Spring 后端以以浏览器需要的方式响应 CORS 预检 OPTIONS 请求,以便将其视为成功。因此,您可能需要花一些时间浏览***.com/search?q=%5Bcors%5D+%5Bspring%5D+options 或***.com/search?q=%5Bcors%5D+%5Bspring-boot%5D+options 完成,我将回复放在第二次更新@sideshowbarker OPTIONS 响应的响应正文与问题无关。事实上,OPTIONS 响应不应该有响应体。您需要检查 OPTIONS 响应的 HTTP 响应标头。您实际上应该在浏览器开发工具中执行此操作,而不是使用 Postman。但我想你可以先用 Postman 检查标题。 我已经更新了“更新 2”@sideshowbarker 您确实想使用浏览器开发工具中的网络窗格来检查响应——响应标头和响应的 HTTP 状态代码。如果浏览器获得的响应与您从 Postman 获得的响应相同,则浏览器不会报告 “预检响应中 Access-Control-Allow-Methods 不允许方法 PATCH” 消息。 【参考方案1】:

好吧,我太白痴了,我自己都不敢相信。我正在使用 [这个 Chrome 插件] 1

它正在修改响应中的标头。感谢@sideshowbarker 注意到它。这是一件很愚蠢的事情,但我敢打赌它也可能发生在其他人身上。

非常感谢@sideshowbarker。

【讨论】:

你救了我的命!我忘记了激活的 CORS 插件,并且我的 Microsoft 图形补丁请求被拒绝,当我关闭插件时,一切都像魅力一样恢复工作 也发生在我身上!谢谢 :) 我正在使用以下插件:chrome.google.com/webstore/detail/allow-cors-access-control/… 你救了我的大脑!我快疯了,完全忘记了那个插件! 感谢您的回答,因为这个 chrome 的 CORS 扩展,我几乎度过了一个不眠之夜。 我也陷入了这个错误。即时禁用该插件并点击“保存”按钮。立即工作。谢谢!【参考方案2】:

我也有同样的问题。我为 CORS 启用了 chrome CORS 插件,似乎它在发出请求之前正在修改标头。禁用它只是工作,这样一个错误:)

【讨论】:

以上是关于JAX-RX - 被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Methods 不允许方法 PATCH的主要内容,如果未能解决你的问题,请参考以下文章

角 POST 请求被 CORS 策略阻止:对预检请求的响应未通过访问控制检查

被 CORS 策略阻止:对预检的响应...没有 HTTP ok 状态。标头没有解决问题

被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP OK 状态

Laravel 7 CORS:被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”

被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权

被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段内容类型 [重复]