1. 程式人生 > >前端-關於CORS跨域的解決方案,面向服務端

前端-關於CORS跨域的解決方案,面向服務端

red 瀏覽器 環境 和我 methods retrieve name 後臺 一件事

最近自己在寫後臺管理系統的時候,並沒有采用jsp、freemaker、葉子等模板技術,而是由後端提供數據api,前端通過AJAX和JQuery來動態操作頁面上的一些div、table元素,從而實現報表的動態加載。

因為本人並非專業前端,所以采用的技術比較古老,對於最近的前端框架,vue,angular,react等等,暫且按下不表。

說說遇到的幾個坑:

1、AJAX發送請求的時候,默認是異步的,而不是同步的。

基於低耦合的編碼,我在寫ajax時,數據請求和數據處理是分開的,沒加同步執行就導致了我的請求發送後,沒有拿到回調的數據就已經開始執行數據處理了。

2、關於非同源鏈接發送異地址的請求,也就是CORS,跨域問題。

瀏覽器出於安全考慮,限制了JS發起跨站請求,使用XHR對象發起請求必須遵循同源策略(SOP:Same Origin Policy),跨站請求會被瀏覽器阻止,這對開發者來說是很痛苦的一件事,尤其是要開發前後端分離的應用時。

在現代化的Web開發中,不同網絡環境下的資源數據共享越來越普遍,同源策略可以說是在一定程度上限制了Web API的發展。

關於跨域問題,只要用ajax來發送請求都會遇到。上個月一直在做一個小程序應用的後端服務接口,前端的朋友並沒有和我放映有跨域問題,估計是小程序底層做了比較良好的封裝,或者底層並不是使用簡單的ajax請求,從而規避了這個問題。

前端如果解決的話,無非就是jsonp,加請求頭,但是這樣會增加前端同事的工作量。

我的解決方案是在後端解決:

(1)最簡陋的方法,在後端web中添加一個filter,這個filter要的過濾順序放在最前面,將對應的HTTP請求加上一個請求頭。

 1 /**
 2  * 解決跨域問題
 3  * Created by huxingyue on 2017/8/31.
 4  */
 5 @WebFilter(filterName = "CORSFilter")
 6 public class CORSFilter implements Filter {
 7     public void destroy() {
 8     }
 9 
10     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws
ServletException, IOException { 11 HttpServletResponse response = (HttpServletResponse) resp; 12 response.setHeader("Access-Control-Allow-Origin", "*"); 13 response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); 14 response.setHeader("Access-Control-Max-Age", "3600"); 15 response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 16 chain.doFilter(req, resp); 17 } 18 19 public void init(FilterConfig config) throws ServletException { 20 21 } 22 23 }

(2)使用@CrossOrigin註解

 1 @RestController
 2 @RequestMapping("/account")
 3 public class AccountController {
 4 
 5     @CrossOrigin
 6     @GetMapping("/{id}")
 7     public Account retrieve(@PathVariable Long id) {
 8         // ...
 9     }
10 
11     @DeleteMapping("/{id}")
12     public void remove(@PathVariable Long id) {
13         // ...
14     }
15 }

這是一個很簡單的示例,官方參考文檔還有更加全面的示例。

 1 <mvc:cors>
 2 
 3     <mvc:mapping path="/api/**"
 4         allowed-origins="http://domain1.com, http://domain2.com"
 5         allowed-methods="GET, PUT"
 6         allowed-headers="header1, header2, header3"
 7         exposed-headers="header1, header2" allow-credentials="false"
 8         max-age="123" />
 9 
10     <mvc:mapping path="/resources/**"
11         allowed-origins="http://domain1.com" />
12 
13 </mvc:cors>

參考文檔:http://spring.io/blog/2015/06/08/cors-support-in-spring-framework

(3)使用第三方CORSFilter

官網:http://software.dzhuvinov.com/cors-filter.html

3、AJAX發送post請求,數據為json時,data對應的內容應該是json字符串,而不是json字符串

參考資料:

http://start.spring.io/

http://www.jianshu.com/p/d05303d34222

前端-關於CORS跨域的解決方案,面向服務端