关于 HTML5、Jquery、Phonegap 跨域问题的研究

       近期研究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是不错的选择。JSONPJSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。但是需要注意服务器端返回数据的格式。对于访问已有的服务器数据不满足jsonp时,应该是不可用的。

           与一般的ajax访问不同的是需要设置dataType="jsonp",注意服务器端返回数据格式。

D、HTML5与跨域

            与HTML5关系密切的跨域技术规范叫跨来源资源共享(CORS)是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略[1],是 JSONP模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支援其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支援 CORS 的老旧浏览器上运作

           值得注意的是同样CORS需要在服务器端配置,也就是说服务器端可以控制访问服务的域名来源,当然,对于没有配置的资源,貌似还是不能访问。

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. header("Access-Control-Allow-Origin:*");   

   实现思路:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. function createCORSRequest(method, url) {  
  2.                 var xhr = new XMLHttpRequest();  
  3.                 if ("withCredentials" in xhr) {  
  4.                       
  5.                     xhr.open(method, url, true);  
  6.   
  7.                 } else if ( typeof (xhr) != "undefined") {  
  8.   
  9.                     xhr = new XDomainRequest();  
  10.                     xhr.open(method, url, true);  
  11.   
  12.                 } else {  
  13.   
  14.                     // 否则,浏览器不支持CORS  
  15.                     xhr = null;  
  16.   
  17.                 }  
  18.                 return xhr;  
  19.             }  
  20.   
  21.             function abc() {  
  22.                 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";  
  23.   
  24.                 var xhr = createCORSRequest('GET', url);  
  25.                 if (!xhr) {  
  26.                     alert('CORS not supported');  
  27.                 } else {  
  28.                     xhr.send();  
  29.                 }  
  30.             }  

应为服务器端没有配置导致不可以跨域访问的提示:

E.服务器端代理

         这种形式在之前的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

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.