JSON数据存在CORS问题

问题描述 投票:0回答:1

运行locally时,在Angular 7应用程序中遇到以下CORS问题。

Access to XMLHttpRequest at 'http://localhost:8080/OnlineOrganicMarket/api/changeorderstatus' from origin 'http://localhost:4200' 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.

我在后端使用Jersey RESTful Web服务框架。仅在标题类型为application/json的情况下会发生这种情况。它适用于application/x-www-form-urlencoded

我认为我的[[CORSFilter类存在问题。

package com.oom.services.filter; import java.io.IOException; import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Priority; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.HttpMethod; import javax.ws.rs.Priorities; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import org.glassfish.jersey.server.ExtendedUriInfo; @Provider @Priority(Priorities.HEADER_DECORATOR) public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter { private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; private static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; private static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers"; private static final String AUTHORIZATION = "authorization"; private static final String ORIGIN = "Origin"; private static String extractAllowedMethods(final ExtendedUriInfo extendedUriInfo) { final Optional<Class<?>> optional = extendedUriInfo.getMatchedRuntimeResources().stream() .flatMap(r -> r.getResources().stream()).flatMap(r -> r.getHandlerClasses().stream()) .filter(r -> r.getPackage().getName().startsWith("com.oom.services")).findFirst(); if (optional.isPresent()) { return Arrays.stream(optional.get().getDeclaredMethods())// .flatMap(m -> Arrays.stream(m.getAnnotations()))// .map(a -> a.annotationType().getAnnotation(javax.ws.rs.HttpMethod.class))// .filter(Objects::nonNull)// .map(HttpMethod::value)// .distinct()// .collect(Collectors.joining(", ")); } // Returning OPTIONS is a bit shady, as ACAM is about *real*, actual methods only. return "OPTIONS"; } @Context private HttpServletRequest request; @Context private ExtendedUriInfo extendedUriInfo; @Override public void filter(final ContainerRequestContext requestContext) throws IOException { final String origin = requestContext.getHeaderString(ORIGIN); if (origin != null && "OPTIONS".equals(requestContext.getMethod())) { request.setAttribute(this.getClass().getName(), true); requestContext.abortWith(Response.ok("CORS OK, carry on.", MediaType.TEXT_PLAIN_TYPE).build()); } } /** * @see https://www.w3.org/TR/cors/ * @see https://jmchung.github.io/blog/2013/08/11/cross-domain-on-jersey-restful-web-services/ * @see https://solutionsisee.wordpress.com/2016/06/30/adding-cors-support-in-jersey-server/ */ @Override public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) throws IOException { final MultivaluedMap<String, Object> responseHeaders = responseContext.getHeaders(); final String origin = requestContext.getHeaderString(ORIGIN); if (origin != null) { // The presence of the Origin header marks a CORS request. responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, origin); responseHeaders.add(ACCESS_CONTROL_ALLOW_METHODS, extractAllowedMethods(extendedUriInfo)); responseHeaders.add(ACCESS_CONTROL_ALLOW_HEADERS, AUTHORIZATION + ", X-Requested-With, Content-Type"); if (requestContext.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS) != null) { responseHeaders.add(ACCESS_CONTROL_ALLOW_CREDENTIALS, requestContext .getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS).toLowerCase().contains(AUTHORIZATION)); } } if (request.getAttribute(this.getClass().getName()) != null) { // We are in a CORS Preflight answer, fast tracked. The entity (== response body) is not // relevant. } } }
我遇到问题的服务部分

@POST @Path("/changeorderstatus") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response updateOrderStatus(OrderBean orderStatus) { JSONArray responseJson = new OrderDAO().updateOrderStatus(orderStatus); return Response.ok(responseJson, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS").build(); }

我尝试通过某些扩展名禁用CORS,并在Chrome浏览器中将其禁用。什么都没用。
java angular maven cors jersey-2.0
1个回答
0
投票

Paul Samsotha最初回答

package com.oom.services.filter; import java.io.IOException; import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Priority; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.HttpMethod; import javax.ws.rs.Priorities; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.container.PreMatching; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import org.glassfish.jersey.server.ExtendedUriInfo; @Provider @PreMatching public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter { /** * Method for ContainerRequestFilter. */ @Override public void filter(ContainerRequestContext request) throws IOException { // If it's a preflight request, we abort the request with // a 200 status, and the CORS headers are added in the // response filter method below. if (isPreflightRequest(request)) { request.abortWith(Response.ok().build()); return; } } /** * A preflight request is an OPTIONS request * with an Origin header. */ private static boolean isPreflightRequest(ContainerRequestContext request) { return request.getHeaderString("Origin") != null && request.getMethod().equalsIgnoreCase("OPTIONS"); } /** * Method for ContainerResponseFilter. */ @Override public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { // if there is no Origin header, then it is not a // cross origin request. We don't do anything. if (request.getHeaderString("Origin") == null) { return; } // If it is a preflight request, then we add all // the CORS headers here. if (isPreflightRequest(request)) { response.getHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); response.getHeaders().add("Access-Control-Allow-Headers", // Whatever other non-standard/safe headers (see list above) // you want the client to be able to send to the server, // put it in this list. And remove the ones you don't want. "X-Requested-With, Authorization, " + "Accept-Version, Content-type, Content-MD5, CSRF-Token"); } // Cross origin requests can be either simple requests // or preflight request. We need to add this header // to both type of requests. Only preflight requests // need the previously added headers. response.getHeaders().add("Access-Control-Allow-Origin", "*"); } } 仍然我不明白为什么我使用的先前代码无法与标头类型

Content-Type-application / json

一起使用,即使它在Access-Control-Allow中具有标头类型Content-Type -标题列表。

© www.soinside.com 2019 - 2024. All rights reserved.