我们正在使用 Spring Restful、oAuth、MVC 服务器端,如果服务器和 Web 应用程序在同一台服务器上运行,它工作正常。
我们在不同域中运行服务器和 Web 应用程序,我们面临无效 session 错误。
当我们进行后调用时,浏览器发出 OPTIONS 请求,但立即后调用失败。
我们启用了 CORS 过滤器,因此 OPTIONS 调用返回 200,但它使当前 session 无效,因此下一个 post 调用失败。
我们没有发送 OPTION 请求,所以直到拦截器仍然是它的无效 session 时它才到达。
我们尝试了以下解决方案:
- 分派(dispatch) OPTIONS 请求并在拦截器中处理它。它正在创建新 session 但无法持久存储它。所以还是失败了
- 在查询参数中发送自定义访问 token header 和 session Cookie,但我们无法在 JavaScript 中访问 session cookie。
我试图避免根据 OPTIONS 请求创建新 session ,请告诉我们如何避免在 Spring 或 Tomcat 中。
我们还需要为混合移动应用程序支持此解决方案(因为它不支持 cookie)。
启用 CORS:
在 web.xml 中:
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.tip.uiux.service.framework.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在 CORSFilter.java 中
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("X-Frame-Options", "DENY");
response.setHeader("Access-Control-Allow-Methods","POST, GET, HEAD, OPTIONS");
response.setHeader("Access-Control-Allow-Headers",
"Custom-Access-Token, Origin, Accept, Session-Alias, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
//LOGGER.info("Request Filtered for Cross Origin Resource Sharing using CORSFilter with custom headers");
chain.doFilter(req, res);
}
最佳答案
您还应该在响应中添加相关的 header 。请在您的应用程序中使用以下 CORS 过滤器。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Autowired
Environment environment;
public CorsFilter() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
if (Arrays.stream(this.environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("development")))) {
response.setHeader("Access-Control-Allow-Origin", "http://dev.yourdomain.com");
} else if (Arrays.stream(this.environment.getActiveProfiles()).anyMatch(env -> (env.equalsIgnoreCase("production")))) {
response.setHeader("Access-Control-Allow-Origin", "https://www.yourdomain.com");
} else {
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
}
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, Authorization, X-Requested-With, Content-Type, Accept, Key");
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() {
}
}
请注意,过滤器还会向 header 添加一些域信息(对于开发和生产环境,默认为 localhost)。如果您想使用它们,您可以为这些部分提供您自己的域。
希望对你有帮助
关于java - Spring Restful : Handling OPTIONS request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45347718/