假设您正在为客户端开发基于JavaScript的项目,并且他通过其余的Web服务向服务器发出Ajax请求,那么您可能会遇到一些麻烦,尤其是如果双方都在单独的域中。
实际上,出于安全原因,未授权从一个域A到另一域B的Ajax请求。
幸运的是,W3C引入了所谓的CORS(跨源资源共享),它为服务器提供了更好地控制跨域请求的可能性。
为此,服务器必须在响应中添加HTTP标头,以向客户端指示允许的来源。
此外,如果您使用自定义标头,则出于安全考虑,浏览器将无法读取它们,因此您必须指定要公开的标头。 因此,如果您无法在JavaScript代码中检索自定义的HTTP标头值,则应阅读下一步
标头列表:
访问控制允许来源
Access-Control-Allow-Origin: <origin> | *
origin参数指定可以访问资源的URI。 浏览器必须执行此操作。 对于没有凭据的请求,服务器可以将“ *”指定为通配符,从而允许任何源访问资源。
访问控制公开标头
Access-Control-Expose-Headers: X-My-Header
此标头使服务器允许浏览器访问的白名单标头。 添加自定义标头时,这非常有用,因为将标头添加到“ Access-Control-Expose-Headers”标头中,可以确保您的浏览器能够读取它们。
访问控制最大年龄
Access-Control-Max-Age: <delta-seconds>
该标头指示可以将预检请求的结果缓存多长时间。
访问控制允许方法
Access-Control-Allow-Methods: <method>[, <method>]*
指定访问资源时允许的一种或多种方法。 用于响应预检请求。 上面讨论了请求被预检的条件。
访问控制允许标题
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
用于响应预检请求,以指示发出实际请求时可以使用哪些HTTP标头。
现在让我们看看如何使用Spring添加此标头
首先,我们需要创建一个实现Filter接口的类:
package hello;
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.HttpServletResponse;
import org.springframework.stereotype.Component;public class CORSFilter implements Filter {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, DELETE");response.setHeader("Access-Control-Allow-Headers", "x-requested-with");response.setHeader("Access-Control-Expose-Headers", "x-requested-with"); chain.doFilter(req, res);}
}
现在,我们只需要将过滤器添加到servlet上下文中:
@Configuration
public class ServletConfigurer implements ServletContextInitializer {@Overridepublic void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {servletContext.addFilter("corsFilter", new CORSFilter());}
}
所有人,您现在可以跨域请求并使用自定义的HTTP标头!
翻译自: https://www.javacodegeeks.com/2014/07/spring-rest-ajax-and-cors.html