Ionic的跨域問題

跨域你們都不陌生,但最近一直遇到一個坑,也是自身對ajax和angular的不深刻形成,因此記錄一筆,下次遇到繞過。html

參考過:http://ionichina.com/topic/54f051698cbbaa7a56a49f98,這上面寫的很清楚,經過Ionic CLI代理服務器來實現跨域,使用gulp來構建,但我嘗試過無效,不知道是不是跟我數據都是post相關,網上不少資料都用jsonp,但jsonp好像也沒法post,由於後端是.net mvc,參數都是用實體類來接收,因此要改爲rest api比較麻煩,後面一直研究跨域的問題,這裏有幾點說明:前端

原本是用vs2015開發ionic + cordova,自己也集成了cordova,直接啓動在ripple模擬器裏能夠設置local的代理,這樣就避免了跨域,但奈何想脫離vs,由於沒可能讓作前端的還要裝個vs,太龐大了,並且vs來作的話環境不是很好搭建,並且那個node_modules目錄層次結構不知道爲何那麼深,拷貝都拷貝不了,總而言之,各類問題,參考資料又太少,仍是用純前端來處理吧,雖然vs開發也有不少優勢,好比remotebuild ios等等。node

goole 的插件:Allow-Control-Allow-Origin: *也安裝了,不知爲什麼也不能跨域,多是由於post的緣由。jquery

後面跟蹤調試,發現其實已經跨域了的,但提示Options....之類的請求,404的問題,而後在後端增長了一個和post方法同名的HttpOptions的方法,也能夠不寫[HttpOptions]特性,這樣的話調試發現會請求兩次,第一次會進這個HttpOptions方法,原來是要先進行預檢測,怎樣去掉這個預檢測呢,後面發現要加上$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';這句,而後發現不會兩次請求了,以前加的那個空方法也能夠刪了。但又發現參數都沒有傳遞過來,後臺Action的參數實體對象的值都爲空,後面又繼續排查,發現參數都提交到request.form裏了,而後就知道了參數提交過來的兩種方式:form data和request.payload,這樣就須要將form data轉換成request.payload,最終的解決辦法是參考:ios

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/angularjs

就解決了。ajax

最終發現升級ionic1.7.14後$ionicView.enter這個事件無效了,還不知道緣由....json

 

最終要說的是,實現ionic 的post跨域,不使用代理和jsonp的方式的解決辦法以下:gulp

1.asp.net mvc服務端配置:後端

 <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>

2.客戶端index.html頁面配置

<meta http-equiv="Content-Security-Policy" content="script-src * 'unsafe-eval'; connect-src * 'unsafe-eval';object-src 'self'; style-src * 'unsafe-inline'; img-src *">

3.客戶端app.js配置

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
                /**
                 * The workhorse; converts an object to x-www-form-urlencoded serialization.
                 * @param {Object} obj
                 * @return {String}
                 */
                var param = function(obj) {
                    var query = '',
                        name, value, fullSubName, subName, subValue, innerObj, i;

                    for (name in obj) {
                        value = obj[name];

                        if (value instanceof Array) {
                            for (i = 0; i < value.length; ++i) {
                                subValue = value[i];
                                fullSubName = name + '[' + i + ']';
                                innerObj = {};
                                innerObj[fullSubName] = subValue;
                                query += param(innerObj) + '&';
                            }
                        } else if (value instanceof Object) {
                            for (subName in value) {
                                subValue = value[subName];
                                fullSubName = name + '[' + subName + ']';
                                innerObj = {};
                                innerObj[fullSubName] = subValue;
                                query += param(innerObj) + '&';
                            }
                        } else if (value !== undefined && value !== null)
                            query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
                    }

                    return query.length ? query.substr(0, query.length - 1) : query;
                };

                // Override $http service's default transformRequest
                $httpProvider.defaults.transformRequest = [function(data) {
                    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
                }];

4.再貼一下LoginService.js的代碼

login: function (user) {
                var deferred = $q.defer();
                var url = commConfig.domain + ‘xxx’
                $http.post(url, user)
                .success(function (data) {
                    //業務處理
                    deferred.resolve(data);
                }).error(function (error) {
                    //業務處理
                    deferred.reject(error);
                });

                return deferred.promise;
            },
相關文章
相關標籤/搜索