我的问题:
近期研究Phonegap的相关技术,遇到了服务资源访问的跨域。经过尝试使用服务器端的代理,Phonegap打包后不能够访问到相应资源。在搜索引擎的帮助下,找到了Jquery的jsonp的方式,尝试发现已有的服务资源返回格式不支持。接着转战CORS发现同样需要服务器端配置,几番折腾,后来发现Phonegap原来就不存在跨域访问的问题。于是乎,使用JqueryMobile的ajax测试,打包安装应用,原来真的可以访问。虽然比较曲折,但是也算对js的相关跨域有了一定的认识,在此总结纪录,以供有同样需求的同学享用!
A、关于跨域
其实跨域访问在日常的web项目开发是及其常见的问题。跨域问题的原因是浏览器的同源策略(same origin policy),它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。
简单讲,同源就是要求域名,协议,端口三者都一致,而同源策略就是指页面上的脚本不能访问非同源的资源。
B、Phonegap与跨域
其实,谈跨域是不应该把Phonegap拉进来的,对于Phonegap本身人家是没有限制的,只需要简单配置即可。因为Phonegap使用的是 file:// 协议(Phonegap wiki里面说: ”The cross-domain security policy does not affect PhoneGap applications. Since the html files are called by webkit with the file:// protocol, the security policy does not apply.”)
但是默认的配置需要检查
b1.Jquery项目里面的相关配置:
$.support.cors=true;
$.mobile.allowCrossDomainPages=true;
b2.Phonegap配置设置:
phongegap2.9.1(cordova/defaults.xml)
找到<access origin="*"/>可以在此处设置需要跨域的域名列表
具体参考官网
http://docs.phonegap.com/en/3.0.0/guide_appdev_whitelist_index.md.html
C、Jquery与跨域
对于Jquery跨域访问,jsonp是不错的选择。JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。但是需要注意服务器端返回数据的格式。对于访问已有的服务器数据不满足jsonp时,应该是不可用的。
与一般的ajax访问不同的是需要设置dataType="jsonp",注意服务器端返回数据格式。
D、HTML5与跨域
与HTML5关系密切的跨域技术规范叫跨来源资源共享(CORS)是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略[1],是 JSONP模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支援其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支援 CORS 的老旧浏览器上运作。
值得注意的是同样CORS需要在服务器端配置,也就是说服务器端可以控制访问服务的域名来源,当然,对于没有配置的资源,貌似还是不能访问。
header("Access-Control-Allow-Origin:*");
实现思路:
function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { xhr.open(method, url, true); } else if ( typeof (xhr) != "undefined") { xhr = new XDomainRequest(); xhr.open(method, url, true); } else { // 否则,浏览器不支持CORS xhr = null; } return xhr; } function abc() { var url = "http://st.geoq.cn/geocode/xxx/single?queryStr=%E5%8C%97%E4%BA%AC%E4%B8%9C%E7%9B%B4%E9%97%A8%E5%8D%97%E5%A4%A7%E8%A1%97&citycode=110000&f=json"; var xhr = createCORSRequest('GET', url); if (!xhr) { alert('CORS not supported'); } else { xhr.send(); } }应为服务器端没有配置导致不可以跨域访问的提示:
这种形式在之前的Flex跨域中也经常使用,Esri也提供了不同服务器的代理页面。但是,问题是它需要对应用进行部署访问。
F.总结
跨域问题是web开发中的普遍问题,同时也是考验前端工程师耐心和能力的试金石。本文就近期研究Phonegap开发中遇到的跨越问题在此总结,与大家分享!
参考资源:
phonegap jQuerymobile 跨域访问
http://blog.csdn.net/mociml/article/details/8880161
http://www.phonegap100.com/article-72-1.html
JqueryMobile中文网站
http://www.jqmapi.com/componts/page/phonegapapp.html
HTML5安全:CORS(跨域资源共享)简介
http://www.html5cn.org/article-5682-1.html