Angular 应用程序仅在 chrome 中出现 CORS 错误
Posted
技术标签:
【中文标题】Angular 应用程序仅在 chrome 中出现 CORS 错误【英文标题】:Angular app gets CORS error only in chrome 【发布时间】:2021-11-16 14:28:57 【问题描述】:在我的 Angular 应用程序(带有远程服务器的本地主机应用程序)上,我只在 chrome 中收到 CORS 错误,在 Firefox 中,它运行良好。 一旦它在两者上都有效,但突然停止在 Chrome 上工作,我猜它与一种更新有关(我猜是 chrome??) Ofcorse,将应用上传到生产服务器在两种浏览器上都可以工作。
我的服务器端代码使用 Java (Servlets),我的 CORSFilter 如下所示:
public class CORSFilter implements Filter
/**
* Default constructor.
*/
public CORSFilter()
/**
* @see Filter#destroy()
*/
public void destroy()
private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200");
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
// Lets make sure that we are working with HTTP (that is, against HttpServletRequest and HttpServletResponse objects)
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse)
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Access-Control-Allow-Origin
String origin = request.getHeader("Origin");
LoggingService.writeToLog("call from origin: "+origin+", will be accepted? "+(allowedOrigins.contains(origin)||origin!=null), LogModule.WebAPI, LogLevel.Debug);
response.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "");
response.setHeader("Vary", "Origin");
// Access-Control-Allow-Credentials
response.setHeader("Access-Control-Allow-Credentials", "true");
// Access-Control-Allow-Methods
response.setHeader("Access-Control-Allow-Methods", "POST,HEAD, PUT, GET, OPTIONS, DELETE");
// Access-Control-Allow-Headers
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-TOKEN");
if (request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_ACCEPTED);
return;
chain.doFilter(req, res);
关于如何使其在 Chrome 中也能正常工作的任何想法?
【问题讨论】:
你得到了什么 cors 错误?,它可能是几个,过滤器看起来很好 此 set-cookie 未指定 samesite 属性,默认为 samesite=lax 并被阻止 我将它添加到服务器代码但没有帮助 这与 cors 无关,与服务器 cookie 配置无关,您必须检查应用程序的实际请求链以正确设置 cookie,也可能 cookie 不是来自后端而不是前端应用程序 嗯,我同意你的看法,这是 cookie 的问题,但它与 CORS 政策有关。我附上了我所做的解决方案 【参考方案1】:该问题与上次更改 SameSite cookie 的 Chrome 浏览器 CORS 策略有关。 对我来说,因为我想启用 CORS,所以我必须添加 SameSite=None 参数。 这是更新的代码。 这是帮助我验证需要做什么的帖子: Set cookies for cross origin requests
请注意,如果您确实需要启用 CORS 选项,则此代码非常有用。这是一个重大决定。
public class CORSFilter implements Filter
private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200");
private final String SESSION_COOKIE_NAME = "JSESSIONID";
private final String SESSION_PATH_ATTRIBUTE = ";Path=";
private final String ROOT_CONTEXT = "/";
private final String SAME_SITE_ATTRIBUTE_VALUES = ";HttpOnly;SameSite=None;Secure";
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
// Lets make sure that we are working with HTTP (that is, against HttpServletRequest and HttpServletResponse objects)
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse)
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Access-Control-Allow-Origin
String origin = request.getHeader("Origin");
LoggingService.writeToLog("call from origin: "+origin+", will be accepted? "+(allowedOrigins.contains(origin)||origin!=null), LogModule.WebAPI, LogLevel.Debug);
response.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "");
response.setHeader("Vary", "Origin");
String requestUrl = request.getRequestURL().toString();
// Access-Control-Max-Age
//response.setHeader("Access-Control-Max-Age", "3600");
// Access-Control-Allow-Credentials
response.setHeader("Access-Control-Allow-Credentials", "true");
// Access-Control-Allow-Methods
response.setHeader("Access-Control-Allow-Methods", "POST,HEAD, PUT, GET, OPTIONS, DELETE");
/*
This the code that i added to the code to use SameSite=None Cookie
*/
boolean isResourceRequest = requestUrl != null ? StringUtils.isNoneBlank(allowedOrigins.stream().filter(s -> requestUrl.contains(s)).findFirst().orElse(null)) : null;
if (!isResourceRequest)
Cookie[] cookies = ((HttpServletRequest) request).getCookies();
if (cookies != null && cookies.length > 0)
List<Cookie> cookieList = Arrays.asList(cookies);
Cookie sessionCookie = cookieList.stream().filter(cookie -> SESSION_COOKIE_NAME.equals(cookie.getName())).findFirst().orElse(null);
if (sessionCookie != null)
String contextPath = request.getServletContext() != null && StringUtils.isNotBlank(request.getServletContext().getContextPath()) ? request.getServletContext().getContextPath() : ROOT_CONTEXT;
response.setHeader("Set-Cookie", sessionCookie.getName() + "=" + sessionCookie.getValue() + SESSION_PATH_ATTRIBUTE + contextPath + SAME_SITE_ATTRIBUTE_VALUES);
/*
End of new code
*/
// Access-Control-Allow-Headers
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-CSRF-TOKEN");
if (request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_ACCEPTED);
return;
chain.doFilter(req, res);
【讨论】:
以上是关于Angular 应用程序仅在 chrome 中出现 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章
Angular 将文件保存为 csv 导致网络错误仅在 Chrome 上
PUT 请求仅在 Chrome 或 Opera 中生成 SPDY 协议错误?
Angular 8 急切加载模块(包括应用程序模块)不会出现在 chrome 开发工具中