当前位置: 首页 > 知识库问答 >
问题:

AJAX cors问题:飞行前响应中的访问控制允许标头不允许请求标头字段访问控制允许凭据

计弘
2023-03-14

我正在从主机(http://abc.com.au)向主机http://localhost:8081上运行的Spring Cloud API网关发送ajax请求。

jquery AJAX请求代码。

SimplifiedAdoptionBulkUpload.jsp

setCookie("username", 'abc', 30);

$.ajax({
            type: "POST",
            enctype: 'multipart/form-data',
            url: "http://localhost:8081/api/v1/users/bulkUpload",
            xhrFields: {
                withCredentials: true
            },
            data: newData,
            processData: false,
            contentType: false,
            crossDomain: true,
            cache: false,
            timeout: 600000,
            success: function (data) {

                .....
                
                
            },
            error: function (e) {
                $('#btnSubmit').prop("disabled", false);
                $('#txtMessage').text('Error Occured');
            
            },
            beforeSend: function (xhr) {
                xhr.setRequestHeader('Authorization', 'Bearer ' + token);
                xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true');
                xhr.setRequestHeader('Access-Control-Allow-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");
                $('body').addClass("loading");
            }
            
        });

spring cloud gateway cors配置。

@Configuration
public class PreFlightCorsConfiguration {

    private static final String ALLOWED_HEADERS = "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization";
    private static final String ALLOWED_METHODS = "*";
    private static final String ALLOWED_ORIGIN = "http://abc.com.au";
    private static final String ALLOWED_EXPOSE = "*";
    private static final String MAX_AGE = "3600";

    @Bean
    public WebFilter corsFilter() {
        return (ServerWebExchange ctx, WebFilterChain chain) -> {
            ServerHttpRequest request = ctx.getRequest();
            if (CorsUtils.isCorsRequest(request)) {
                ServerHttpResponse response = ctx.getResponse();
                HttpHeaders headers = response.getHeaders();
                headers.set("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
                headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
                headers.add("Access-Control-Max-Age", MAX_AGE);
                headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
                headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
                headers.add("Access-Control-Allow-Credentials", "true");
                if (request.getMethod() == HttpMethod.OPTIONS) {
                    response.setStatusCode(HttpStatus.OK);
                    return Mono.empty();
                }
            }
            return chain.filter(ctx);
        };
    }
}

我在chrome控制台中遇到以下错误。

SimplifiedAdoptionBulkUpload:1访问'http://localhost:8081/api/v1/users/bulkUpload'从原点'http://abc.com.au'已被CORS策略阻止:飞行前响应中的访问控制允许标头不允许请求标头字段访问控制允许凭据。

更新:

我从ajax请求中删除了这一行。

xhr.setRequestHeader('Access-Control-Request-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");

我在jsp和servlet过滤器中设置两个cookie(accces_token,refresh_token)。

public class AdminSecurityFilter implements Filter {


 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        boolean error = false;

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        request.setCharacterEncoding("UTF-8");


        if(authenticated) {
                    String accessToken = getUserAccessToken(userStr,passStr);
                    if(!accessToken.isEmpty()) {
                    Cookie cookie = new Cookie("access_token", accessToken);
                    cookie.setPath("/");
                    //cookie.setHttpOnly(true);
                    //cookie.setDomain("localhost");
                    //TODO: When in production must do cookie.setSecure(true);
                    cookie.setMaxAge(3600);
                    response.setHeader("Access-Control-Allow-Credentials", "true");
                    response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");

                    response.addCookie(cookie);
                    }
                    
                    if(!refreshToken.isEmpty()) {
                        Cookie cookie = new Cookie("refresh_token", refreshToken);
                        cookie.setPath("/");
                        //cookie.setHttpOnly(true);
                        //cookie.setDomain("localhost");
                        //TODO: When in production must do cookie.setSecure(true);
                        cookie.setMaxAge(10000);
                        response.setHeader("Access-Control-Allow-Credentials", "true");
                        response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");

                        response.addCookie(cookie);
                    }
                }


}

同样在jsp文件中,我使用jquery设置值cookie。

 function setCookie(cname,cvalue,exdays) {
              var d = new Date();
              d.setTime(d.getTime() + (exdays*24*60*60*1000));
              var expires = "expires=" + d.toGMTString();
              document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
            }

setCookie("username", 'Nirangaa', 30);

但是这些cookie值(用户名、refresh_token、access_token)在Spring Cloud网关的标头中丢失。为什么AJAX请求没有将请求后附加的cookie值发送到apigteway端。@T. J.克劳德感谢您解释为什么会这样

@Component
public class AccessTokenCheckingGlobalFilterPre extends AbstractGatewayFilterFactory<AccessTokenCheckingGlobalFilterPre.Config> {


    public AccessTokenCheckingGlobalFilterPre() {
        super(AccessTokenCheckingGlobalFilterPre.Config.class);
    }

    @Override
    public GatewayFilter apply(AccessTokenCheckingGlobalFilterPre.Config config) {
        return (exchange, chain) -> {
             Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
             ServerHttpRequest request = null;
             if (route != null) {
                
                
                 request = exchange.getRequest();
                 
                 
                 
                 **//[Host:"localhost:8081", Connection:"keep-alive", Content-Length:"7391", Accept:"*/*", Access-Control-Allow-Credentials:"true", Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiamFjcGx1c19yZXNvdXJjZSJdLCJFeHBpcmVzSW4iOjM1OTksInVzZXJfbmFtZSI6Im5zYW5kYXJ1d2FAd2lsZXkuY29tIiwic2NvcGUiOlsiUkVBRCxXUklURSJdLCJleHAiOjE2MTUxOTQwNjIsInVzZXJOYW1lIjoibnNhbmRhcnV3YUB3aWxleS5jb20iLCJhdXRob3JpdGllcyI6WyJST0xFX0FkbWluaXN0cmF0b3IiLCJST0xFX3RlYWNoZXIiLCJST0xFX3NjaGFkbWluIiwiUk9MRV9zdHVkZW50Il0sImp0aSI6IjBkMjQ3ZjJkLTg0NjgtNDUwYS04NjI3LTAzOGI4ZmRlZjQ2MCIsImNsaWVudF9pZCI6ImphY3BsdXMifQ.GT0ayX01TO0fNY834n5_vXsqmt2P3s2C7hfMH-_FLvsNT-p9uIj5i0U66ZdouDUaL9xu1iy4wdfxLexfvilwnO10fTX5I0U7DHqHQetLUwCJOhET0hN-PyFcJRe7k3C3BUe8f7iuDd6Y4VbLCYTTpp4KSjWcS5fv-BTrvTvktwtkq5oFK2iCtPS6JwqPcFsvt2MYNi9UlGFeik_a-iyuTTa7xf7VgL2XFnGqcu3bOTUNxj4AhG91YL5har3OnFTbZnKFxVWykEz7MJFSXzmhmSS5rNYAbC5FBg65VFmzD0j9G4j1xPODxmLEEeE2Qj5FSe6VTnEZIiFHTLd27IuYyA", User-Agent:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36", Origin:"http://abc.com.au", Content-Type:"multipart/form-data; boundary=----WebKitFormBoundaryV5bORQSNHAa3kxFR", Referer:"http://admin.jacplus.com.au/admin/SimplifiedAdoptionBulkUpload", Accept-Encoding:"gzip, deflate, br", Accept-Language:"en-US,en;q=0.9"]**

                 HttpHeaders headers = request.getHeaders();
                 
                 
                 
                 
                 
                 
                 
                 List<String> authorizationHeader = headers.get(HttpHeaders.AUTHORIZATION);
                 String value = authorizationHeader.get(0);
                 
                 MultiValueMap<String, HttpCookie> cookies = request.getCookies(); /// nulll 

                
                 
             }
             
             return chain.filter(exchange.mutate().request(request).build());
            
            
            
        };
    }

共有1个答案

董元徽
2023-03-14

Access-Control-Allow-XYZ标头是响应标头,而不是请求标头。将它们从您的$. ajax调用中删除。您可能需要Access-Control-Request est-XYZ标头,例如:

xhr.setRequestHeader('Access-Control-Request-Headers', "Origin,Cookie,X-Requested-With, Content-Type, Accept, Authorization");
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^

这是一个有效的请求头。(但是,CORS规范中没有列出访问控制请求凭据头,因此添加访问控制允许凭据头的另一行应该删除。)

更一般地说,请求中的任何标头都必须由您的响应的Access-Control-Allow-Headers值允许,而您的响应中没有该值。但修复方法是从请求中删除它,而不是将其添加到Access-Control-Allow-Headers值中。

另见:CORS规范

 类似资料:
  • 我在后端使用spring boot服务,在前端使用angular 6。 在spring boot中,我使用启用了cors。 并且我正在为每个服务使用拦截器。 在前端呼叫服务中: 如果使用拦截器,我会得到以下异常。如果不使用隔膜,我不会得到cors错误。 加载失败http://localhost:7070/example/myservice:飞行前响应中的访问控制允许标头不允许请求标头字段访问控制允

  • 我正在创建一个单页应用程序使用sails.js和reactjs,并使用JWT作为受保护请求的身份验证。在登录过程中,登录请求按预期工作,并能够成功登录。之后,当我试图用无记名请求其他请求时,浏览器显示以下错误消息。 从源访问位于“http://localhost:1337/monitoring URL”的XMLHttpRequest 以下是我在帆config/security.js中的cors设置

  • 如何解决以下错误; 加载资源失败:服务器响应状态为500(内部服务器错误)cdn。安普项目。org/v0。js:68响应必须包含AMP访问控制允许源代码源标题Yd@cdn。安普项目。org/v0。js:68 cdn。安普项目。org/v0。js:68表单提交失败:错误:响应必须包含AMP Access Control Allow Source Origin标头​​​ 报道 遵循CORS上AMP G

  • 如何在AngularJS应用程序上设置我的. htaccess以防止以下错误消息: 加载失败:请求标头字段授权在飞行前响应中不被访问控制允许标头允许。 这是我的文件: 每当用户试图提交联系表单时,我都会在我的网站上收到错误消息。 这是我的流程代码:

  • 我使用axios调用api和承载令牌的方式进行授权,我的代码: 在用户存储库中。js时,将导入存储库并通过以下方式调用api: 然后错误是"未授权",但当我更新头: 错误是:在'http://example.com/users“起源”http://localhost:8080'已被CORS策略阻止:飞行前响应中的访问控制允许标头不允许请求标头字段访问控制允许来源。

  • 我正在开发一个带有jhipster V4.5.6的Spring启动应用程序。但无法配置 CORS。 下面是我的application-dev.yml文件: WebConfigurer.java如下: 和安全配置。java文件如下所示: 现在,我可以使用 GET 请求。但是当我使用POST时,如下所示: 我得到以下错误: XMLHttpRequest 无法加载 http://localhost:80