跨域你們都不陌生,但最近一直遇到一個坑,也是自身對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; },