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;
            },
时间: 2024-10-17 15:39:23

Ionic的跨域问题的相关文章

通过设置Ionic-Cli代理解决ionic serve跨域调试问题

Ionic-Cli代理设置: 打开ionic.config.json文件,添加proxies代理配置字段: { "name": "ion", "app_id": "", "v2": true, "typescript": true, "proxies": [ { "path": "/web", "proxyUrl&qu

解决 ionic 中的 CORS(跨域)

译者注:本人翻译功力有限,所以文中难免有翻译不准确的地方,凑合看吧,牛逼的话你看英文版的去,完事儿欢迎回来指正交流(^_^) 如果你通过 ionic serve 或者 ionic run 命令使用或 live reload 或者访问过外部 API 结点,那么你肯定遇到过 CORS 问题,譬如下面这样: XMLHttpRequest cannot load http://api.ionic.com/endpoint. No 'Access-Control-Allow-Origin' header

angularjs+webapi2 跨域Basic 认证授权(一)

如今的app,利用各种前端框架结合html5的混合开发模式已然盛极一时.其中ionic+angularjs更是如日中天.这种模式利用angularjs $http 请求数据api 以达到前后端分离深得人心.说到webapi 跨域和认证授权始终是不得不提的.这种现成的例子有很多,但我发现的要么是过于复杂,不利于第一次有效理解整个过程:要么就是侧重点比较单一,不好囊括:要么就是其中有些坑没有踩到,换个环境就一头雾水. 所以,我打算以最简单的实现方式最大限度地寻找其中的一些坑和注意点. 1.来看看我们

js跨域

第一次写博客,好紧张,不知道能写成啥样,哈哈哈. 自己的一知片解,有错请多多指教,嘻嘻嘻. 一.何为跨域? 只要协议.域名.端口后任何一个不同,就是跨域. 举个例子: http://www.example.com 协议不同 https://www.example.com http://www.example.com 域名不同 http://www.test.com http://www.example.com 端口不同 http://www.example.com:81 注意:ip相同,域名不同

实现AJAX跨域访问方式一

1.添加pom依赖 <dependency> <groupId>com.thetransactioncompany</groupId> <artifactId>cors-filter</artifactId> <version>2.6<ersion> <!--<scope>runtime</scope>--> </dependency> 2.在web.xml 中增加配置 &l

原生jsonp跨域

<script> // jsonp跨域原生写法 var script = document.createElement('script'); script.src = 'http://192.168.7.16/kuayu/test02.php?callback=aa'; document.body.appendChild(script); //aa('后台数据') function aa(res) { alert(res.website); } </script>

跨域cors方法(jsonp,document.domain,document.name)及iframe性质

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作是不同的域. 下表给出了相对 http://store.company.com/dir/page.html 同源检测的结果: 要解决跨域的问题,我们可以使用以下几种方法: 1.通过jsonp跨域[解决ajax跨域] 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的

什么是跨域?怎么解决跨域问题?

什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. 所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子: http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域) http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

AJAX跨域实现

原理:在同域中建立一个用于请求 别的域的代理程序,并将返回的内容发给客户端,客户端指向同域的这个代理程序 1. 客户端编写 // 其它部分都一样 //2.注册回调方法 callback xmlhttp.onreadystatechange = callback; //获取客户端内容 var userName = document.getElementById("UserName").value; //进行编码解决 中文乱码 userName = encodeURI(encodeURI(