同源
URL由协议, 域名, 端口组成. 如果两个URL的协议, 域名, 端口相同, 那么这两个URL为同源.
同源策略
script, iframe, link 可以跨域加载一些静态资源, 比如脚本语言, CSS, 图片等, 但脚本语言不能访问其他域的HTML文档. 因为同源策略, 所以在客户端和服务器不在同一域下时, 请求需要跨域.
CORS
使用CORS解决跨域请求问题, 需要浏览器和服务器同时支持, 目前基本上所有的浏览器都支持CORS通讯过程.
请求部分由浏览器自动完成, 是否能通过CORS完成跨域请求, 主要看服务器端实现对响应头的修改.
CORS使用自定义的HTTP头部使客户端与服务器沟通, 在服务器端进行配置. 可以通过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.HttpServletResponse; public class HeaderCorsFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse resp = (HttpServletResponse) response; resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); resp.setHeader("Access-Control-Max-Age", "3600"); resp.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization"); resp.setHeader("Access-Control-Allow-Credentials","true"); chain.doFilter(request, resp); } public void destroy() { // TODO Auto-generated method stub } }
Access-Control-Allow-Origin
添加Origin字段来表明, 请求来自哪个源, 要么是一个请求的范围, 要么是" * ", 表明任意域可以请求.
Access-Control-Allow-Credentials
设置客户端请求是否可以带身份凭证, 是一个boolean类型的值, 如果允许携带, 则Origin的范围不能是" * ".
Access-Control-Expose-Headers
XMLHttpRquest对象的getResponse只能获取Cache-Control,
Content-Language,
Content-Type,
Expires,
Last-Modified,
Pragma六个字段, 如果想获取其他的字段, 需要在这里指定.
Access-Control-Allow-Methods
设置允许网络请求的方式.
<filter> <filter-name>cors</filter-name> <filter-class>HeadercorsFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>开放的接口路径</url-pattern> </filter-mapping>
简单请求和非简单请求
...