我曾多次遇到CORS问题,通常可以解决它,但我想通过从MEAN堆栈范式中看到这一点来真正理解。
之前我只是在我的快速服务器中添加了中间件来捕获这些东西,但它看起来像有某种预挂钩,使我的请求出错。
在preflight响应中,Access-Control-Allow-Headers不允许请求报头字段Access-Control-Allow-Headers
我假设我可以这样做:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers","*")
})
或者等价的,但这似乎不能解决问题。我当然也试过
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})
还是不走运。
如果您试图在请求标头上添加自定义标头,则必须让服务器知道允许发生特定的标头。在过滤请求的类中执行此操作。在下面的例子中,自定义头名称为"type":
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, type ");
response.setHeader("Access-Control-Expose-Headers","Authorization");
}
}
当我们为请求定制报头时,会出现这个问题。此请求使用HTTP OPTIONS并包含几个头。
此请求所需的头是Access-Control-Request-Headers,它应该是响应头的一部分,并且应该允许来自所有源的请求。有时在响应头中也需要Content-Type。所以你的响应头应该是这样的
response.header("Access-Control-Allow-Origin", "*"); // allow request from all origin
response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");
在Post API调用中,我们在请求体中发送数据。因此,如果我们将通过向API调用添加任何额外的头来发送数据。然后第一个OPTIONS API调用会发生,然后post调用会发生。因此,您必须首先处理OPTION API调用。
你可以通过编写一个过滤器来处理这个问题,在里面你必须检查选项调用API调用并返回一个200 OK状态。下面是示例代码:
package com.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.Response;
public class CustomFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest httpRequest = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
response.setStatus(Response.SC_OK);
}
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {
// TODO
}
public void destroy() {
// Todo
}
}