當前位置: 首頁>>編程語言>>正文


如何正確實現Spring+angularjs POST跨域提交

1. 先來看看跨域時到底發生了什麽?

cross_request

​ 當瀏覽器端發生js向服務端發送跨域請求時,瀏覽器會判斷是否跨域,如果是跨域請求,則會在發送真實請求前,發送一次OPTIONS(如圖(1))預檢請求,服務器端會根據預檢請求header判斷是否滿足跨域條件;當服務端預檢符合跨域條件,則瀏覽器(Browser)才會再發送真實的請求(如圖(2))至服務器端,請求通過即可正確返回,否則,會返回如下錯誤:XMLHttpRequest cannot load ‘http://localhost:8080/security/crossDomain’. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:63342’ is therefore not allowed access.

​ angularjs跨域提交成功,chrome瀏覽器的請求記錄如下圖:

image

​ 從截圖可以看出,angularjs發送跨域請求時提交了2次同樣的請求,第一次請求為options方法,第二次才是post提交數據的方法。


2. 如何使用spring + angularjs實現跨域POST提交

2.1 服務端Server實現,添加header屬性如下

response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE");
response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");

​ PS:在SpringMVC框架中,需要將這段代碼加入自定義filter中進行全局過濾處理,否則直接放在具體的業務controller可能會無效;另外在自定義interceptor添加這段代碼也會無效,原因是跨域第一次OPTIONS預檢請求在filter階段就驗證不通過,根據HttpServletRequest執行的順序(listen->filter->servlet),interceptor類無法攔截OPTIONS請求。

2.2 前端angularjs實現POST跨域提交

var app = angular.module('app', []);
app.factory('requestInterceptor', ['$q', requestInterceptor]);
function HttpInterceptor($q) {
    return {
        request: function(config){
            config.headers = config.headers || {};
            config.headers['Authorization'] = "uShoSR0Oyy1bpgfZ/48VjyrnmjC3ALDv65KN+o+eQ04=";
            return config || $q.when(config);
        }
    };
}
// 全局攔截器,跨域Post數據默認提交格式為application/x-www-form-urlencoded 通過攔截器修改為application/json
app.config(['$httpProvider', function($httpProvider){
    $httpProvider.interceptors.push("requestInterceptor");
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/json';
}]);

app.controller('siteCtrl', function($scope, $http) {
    $http({
        method:'POST',
        url:'http://localhost:8080/security/crossDomain',
        data:{"biz":"biz100010"}
    }).success(function(req){
        console.log(req);
    })
});

2.3 Spring Controller獲取POST數據

@RequestMapping("/crossDomain")
@ResponseBody
public String crossDomain(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
    System.out.println("requestBody:" +requestBody);
    return "success";
}

​用注解@RequestBody的方式獲取browser端提交的數據data,在這裏使用request.getParameter(“biz”)的值為null.

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/2252.html,未經允許,請勿轉載。