這個問題的原由在於現代瀏覽器默認都會基於安全緣由而阻止跨域的ajax請求,這是現代瀏覽器中必備的功能,可是每每給開發帶來不便。java
但跨域的需求卻一直都在,爲了跨域,勤勞勇敢的程序猿們想出了許許多多的方法,例如,jsonP、代理文件等等。但這些作法增長了許多沒必要要的維護成本,並且應用場景也有許多限制,例如jsonP並不是XHR,因此jsonP只能使用GET傳遞參數。web
在移動應用風生水起的現在,託HTML5的福,Mobile Web,甚至Hybird App也逐漸火起來,在本地文件系統的Web頁面,也有須要獲取外部數據的需求,而這些需求也必然是跨域的。同時,HTML5也來帶了叫「Cross-Origin Resource Sharing」的新特性,來賦予開發者權力決定資源是否容許被跨域訪問。ajax
如何解決?spring
CORS,CrossOrigin Resources Sharing,也即跨源資源共享,是 HTML5 的一項特性,它定義了一種瀏覽器和服務器交互的方式來肯定是否容許跨域請求。json
經過服務器增長一個特殊的Header[Access-Control-Allow-Origin]來告知客戶端跨域的限制,若是瀏覽器支持CORS的話,若是判斷Origin經過的話,就會容許XHR進行請求,而不須要再使用jsonP或者代理文件。跨域
使用這個Header返回被容許請求跨域請求的來源域,例如網站duelist.cn設置了下面的Header瀏覽器
Access-Control-Allow-Origin: http://smdcn.net安全
這樣設置以後,經過http://smdcn.net下的頁面對於duelist.cn進行ajax請求就會被容許,而其餘網站對duelist.cn依舊會被阻攔,經過這種方式網站擁有者能夠本身對此進行限制。服務器
固然,若是不想限制來源,能夠經過app
Access-Control-Allow-Origin: *
來容許任何站點對該資源進行跨域請求
定義SimpleCORSFilter
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; @Component public class SimpleCORSFilter implements Filter { 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-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} }
web.xml:
<filter> <filter-name>cors</filter-name> <filter-class>com.app.filter.SimpleCORSFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>