Ionic的跨域問題


跨域大家都不陌生,但最近一直遇到一個坑,也是自身對ajax和angular的不深入造成,所以記錄一筆,下次遇到繞過。

參考過: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等等。

goole 的插件:Allow-Control-Allow-Origin: *也安裝了,不知為何也不能跨域,可能是因為post的原因。

后面跟蹤調試,發現其實已經跨域了的,但提示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,最終的解決辦法是參考:

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

就解決了。

最終發現升級ionic1.7.14后$ionicView.enter這個事件無效了,還不知道原因....

 

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

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;
            },

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM