我有一个API,它带有两个头ACCESS_TOKEN和TIME_OF_CALL以及输入参数,如下所述。
@RequestMapping(value = "/pay/capture", method = RequestMethod.GET)
@ResponseBody
@CrossOrigin(allowedHeaders = "ACCESS_TOKEN,TIME_OF_CALL", origins = "*")
public ResponseEntity<?> fetchRazorPayDetails(@RequestParam("id") Long id)
{/***logics here*/}
从本地主机点击此API返回401说
XMLHttpRequest cannot load http://soandsoURL , response to preflight doesn't pass access control. check No Access-Control-Allow-Origin Header is present on the requested resource. origin 'http://localhost:1234' is therefore not allowed access. The response had HTTP status code 401
即使我已经明确注释了
@CrossOrigin(allowedHeaders =&#34; ACCESS_TOKEN,TIME_OF_CALL&#34 ;, originins =&#34; *&#34;)
接受所有来源和两个提到的标题。我错过了什么吗? 或者值为allowHeaders不能以逗号分隔?有关此问题的任何帮助 将不胜感激。
答案 0 :(得分:1)
您可以添加自定义过滤器:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
答案 1 :(得分:0)
这只是因为我用@CrossOrigin声明/添加选项。早些时候它是`
@RequestMapping(value = "/pay/capture", method = RequestMethod.GET)
@ResponseBody
@CrossOrigin(allowedHeaders = "ACCESS_TOKEN,TIME_OF_CALL", origins = "*")
public ResponseEntity<?> fetchRazorPayDetails(@RequestParam("id") Long id)
{/***logics here*/}`
我从@CrossOrigin中删除了可选参数,并将其保存为
@RequestMapping(value = "/pay/capture", method = RequestMethod.GET)
@ResponseBody
@CrossOrigin
public ResponseEntity<?> fetchRazorPayDetails(@RequestParam("id") Long id)
{/***logics here*/}
并且有效。
答案 2 :(得分:-1)
在自定义过滤器类中执行以下操作:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = this.getAsHttpRequest(req);
HttpServletResponse httpResponse=this.getAsHttpResponse(res);
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, authorization, ACCESS_TOKEN, TIME_OF_CALL");
chain.doFilter(req, res);
}
private HttpServletResponse getAsHttpResponse(ServletResponse response)
{
if (!(response instanceof HttpServletResponse)) {
throw new RuntimeException("Expecting an HTTP request");
}
return (HttpServletResponse) response;
}
private HttpServletRequest getAsHttpRequest(ServletRequest request)
{
if (!(request instanceof HttpServletRequest)) {
throw new RuntimeException("Expecting an HTTP request");
}
return (HttpServletRequest) request;
}
并且在WebSecurity类中这样做。它会起作用
//To allow Pre-flight [OPTIONS] request from browser
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}