编译为EXE后, jQuery.ajax() 跨域问题 (aardio语言)

657 阅读11分钟
原文链接: bbs.aardio.com
查看: 16139|回复: 16

解决编译为EXE后, jQuery.ajax() 跨域问题

    [复制链接]
analytys 10主题108帖子

623

积分

三级会员

Rank: 4

发表于 2011-5-6 16:55:16 | 只看该作者 回帖奖励
我用jQuery easyui做程序界面,由于界面里面涉及到了数据库和datagrid,所以需要用到ajax。
本来这一切没有什么问题,所有的文件都在一个文件夹内,根本不涉及到ajax的跨域问题,可是,我想把所有的html、js以及ajax所需要请求的json文件都编译进exe时,问题出来了。
编译进exe以后,jquery的ajax被提示拒绝访问。几经查找,发现问题,exe中的资源文件不可被访问。假如我需要用jquery去ajax请求同目录下的test.json文件,也就是说即使jquery.js和test.json都编译进了exe中,ajax仍然失败。这样的话,即使是使用iframe或jsonp都无法解决此ajax跨域问题。

几经思考,想出了解决方案。aardio能和js交互,为解决这个问题提供了莫大的方便。

解决思路:
aardio可以随意访问一个本地或他域文件,如果将javascript的ajax请求的核心函数改成aardio下载或读取一个文件,就永远不要再考虑ajax的跨域请求问题了,实际上也就相当于没有使用ajax了。

我就以jquery为例,简单的用代码描述一下吧。

jquery的ajax函数是 $.ajax();

更改这个函数为:
  1. $.ajax = function(opt){
  2.                 if(opt.success){
  3.                         opt.success.call(opt)
  4.                 }
  5.         }
复制代码在使用这个函数的地方:
  1. $.ajax({
  2. url:'/test.json',
  3. success:function(data){
  4.        data = load(this.url);
  5.       //your code here
  6. }
  7. });
复制代码load 函数是读取文件的函数,这是一个aardio函数,使用web.script可以很简单的写出来,这里省略……

当然,也可以有直接改变$.ajax函数,将load函数读取的数据传给data。这样在使用的时候就不需要data = load(this.url);这一步

个人觉得这样的解决方法相对比较完美,不过以上分析仅是个人愚见,由于个人觉得web做界面最难解决的就是ajax问题,所有拿来和大家探讨下
例子这里:dl.dbank.com/c03rfs9xqb

老大看看觉得好的话可以加到范例里面


分享到:  QQ好友和群 收藏10 分享 顶3 enjoy my life !
游戏 23主题310帖子

1798

积分

荣誉会员

Rank: 8Rank: 8

发表于 2011-5-7 14:34:32 | 只看该作者

支持一下

支持一下
jsniu 7主题161帖子

1000

积分

四级会员

Rank: 6Rank: 6

发表于 2011-5-7 17:42:53 | 只看该作者

能否这样实现呢?在运行时先将exe中所有的文件写出到一个临时文件夹中,这样就能直接访问各文件了。等运行完成,关闭软件前再删除临时文件夹。

能否这样实现呢?在运行时先将exe中所有的文件写出到一个临时文件夹中,这样就能直接访问各文件了。等运行完成,关闭软件前再删除临时文件夹。

点评

这样的方法我考虑过,但是这样的话对于本地开发调试带来了麻烦  发表于 2011-5-7 21:01
有眼界才有境界,有实力才有魅力,有思路才有出路!
使用20%的努力,带动80%的资源,创造100%的成功!
roking 5主题64帖子

755

积分

荣誉会员

Rank: 8Rank: 8

发表于 2011-5-8 18:58:01 | 只看该作者

[i=s] 本帖最后由 roking 于 2011-5-8 18:59 编辑 [/i] ajax请求exe的资源存在特殊性,修改$.ajax 函数影响面有些广

本帖最后由 roking 于 2011-5-8 18:59 编辑

ajax请求exe的资源存在特殊性,修改$.ajax 函数影响面有些广,如果请求非exe资源的其他网络数据的话,你的load函数中得分不同的情况进行处理,工作量大些。针对Jquery easyUI的datagrid控件,他装入数据除了设置url属性外,还可以使用它的loadData方法来进行:

jQuery("#test").datagrid("loadData",jQuery.parseJSON( getData()));

这里getData()是类似你方案中的load aardio函数,进行读取json串的功能,解决访问exe资源的问题。
同时又要访问其他非exe资源的网络数据的话,使用JQuery本身的getScript方法进行跨域访问,我测试当资源打包到exe时,getScript方法可以跨域,而getJSON不成功,不打包的话都可以。你可以用下面的html打包到exe中测试:
  1. <html> <head>
  2.         <script src="jquery-1.6.js"></script>
  3. <script>
  4. window.myCallBack = function(data){
  5.         alert(data.title);
  6. };
  7. $(function() {
  8.         $.getScript("http://api.flickr.com/services/feeds/photos_public.gne?tags=cats&tagmode=any&format=json&jsoncallback=myCallBack");
  9. });
  10. </script>
  11. </head>
  12. <body>
  13.         waiting...
  14. </body>
  15. </html>
复制代码---------------------------------
不知道JQuery的ajax请求关于url的处理有啥特殊地方,我手写了最简单的ajax调用,全打包到exe后,却可以执行,不存在“禁止访问”的情况,不知道是啥原因(见附件)

点评

roking老大好久不见  发表于 2011-5-8 19:54
山外青山天外天,白云深处有神仙。神仙本是凡人做,只怕凡人志不坚。
analytys 10主题108帖子

623

积分

三级会员

Rank: 4

 楼主| 发表于 2011-5-8 21:17:06 | 只看该作者

[quote][size=2][color=#999999]roking 发表于 2011-5-8 18:58[/color] [url=forum.php?m

roking 发表于 2011-5-8 18:58
ajax请求exe的资源存在特殊性,修改$.ajax 函数影响面有些广,如果请求非exe资源的其他网络数据的话,你的l ...
针对Jquery easyUI的datagrid控件,他装入数据除了设置url属性外,还可以使用它的loadData方法来进行:

jQuery("#test").datagrid("loadData",jQuery.parseJSON(getData()));

loadData方法的确是能解决我遇到的问题。但是针对javascript在exe中的ajax问题:
  1. 我测试当资源打包到exe时,getScript方法可以跨域,而getJSON不成功
复制代码jquery的ajax核心函数是$.ajax,其他的$.getScript,$.getJSON,以及$.get,$.post等都是调用的$.ajax函数,所以getScript方法也是不可能跨域的,而你给出的这段代码,应该是jsonp的返回形式,返回后直接调用回调函数,jquery的jsonp能解决跨域问题,但是对于只想返回数据而不是调用回调函数去处理数据的情况下,这样就不太适用了。
  1. JQuery的ajax请求关于url的处理有啥特殊地方
复制代码jquery的ajax请求对url没有做特殊的处理
  1. 我手写了最简单的ajax调用,全打包到exe后,却可以执行,不存在“禁止访问”的情况,不知道是啥原因(见附件)
复制代码我测试过了,的确没有拒绝访问的问题,不过ie6不支持你写的这种ajax,需要ActiveXObject对象,而jquery考虑了使用ActiveXObject创建ajax对象,有可能是这个ActiveXObject的问题。
看来还得再好好深入研究下

点评

同意: 5.0 同意: 5
确实从$.ajax入手解决此问题才是最灵活、最根本的  发表于 2011-5-8 22:32
enjoy my life !
Jacen.He 118主题1606帖子

9040

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2011-6-21 16:30:06 | 只看该作者

[b][size=6]方法一: [/size][/b] 在jQuery源码中找到: [quote]rlocalProtocol = /^(?:about

方法一:

在jQuery源码中找到:
rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,

然后替换为下面的代码
rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,

方法二:

$( function (){
    $.ajax({
        url: 'test.html' ,
        success: function (data){
            $( '#a' ).html(data);
        },
         isLocal:true
    });
});

注意红色部分是添加的代码。






点评

同意: 5.0 同意: 5
老大研究jQuery研究得透彻  发表于 2011-6-21 18:33
最近几天忙着彻底重写Python扩展库!
analytys 10主题108帖子

623

积分

三级会员

Rank: 4

 楼主| 发表于 2011-6-21 20:54:04 | 只看该作者

[quote][size=2][color=#999999]Jacen 发表于 2011-6-21 16:30[/color] [url=forum.php?m

Jacen 发表于 2011-6-21 16:30
方法一:

在jQuery源码中找到:

的确很透彻,这下太好啦
enjoy my life !
Jacen.He 118主题1606帖子

9040

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2011-6-21 20:57:49 | 只看该作者

V067.1可以更加简洁的支持jQuery了,下面是范例(可自动加载jQuery库) [color=#0000ff]import[/color][colo

V067.1可以更加简洁的支持jQuery了,下面是范例(可自动加载jQuery库)

import win.ui;
/*DSG{{*/
var winform = win.form(parent=...; bottom=249;scroll=1;text= "aardio Form" ;right=349 )
winform.add(  )
/*}}*/

import web.form;

//创建web窗体
var wb = web.form( winform )

html = /**
    <div id="idTest" class="style2">
    测试文本
    </div>
   
    <div id="idTest2" class="style2">
    测试文本
    </div>
**/
wb.write(html)

winform.show();

jele = wb.jQuery( "#idTest" ); //根据id取单个节点
winform.msgbox( jele.text() )
jele.text( "Query有意思的是可以使用CSS的语法匹配一个节点的集合
并将他们封装为一个组合,操作组合里所有对象一如操作一个对象,由jQuery自动完成循环操作" )

jele = wb.jQuery( ".style2" ) //根据css样式取节点的集合
jele.css( "font-size" , "15pt" )

jele = wb.jQuery( "div" ) //根据html tag取节点的集合
jele.css( "color" , "red" )

winform.msgbox( "点确定隐藏指定节点" )
jele.hide();

//进入消息循环
win.loopMessage();
return winform,wb;

是不是看不到任何加载jQuery库的代码?加载过程已经由标准库自动支持了。



最近几天忙着彻底重写Python扩展库!
51ak 23主题412帖子

2244

积分

五级会员

Rank: 8Rank: 8

发表于 2011-6-21 22:29:12 | 只看该作者

好东西,网页操作更进一步。安逸哈。

好东西,网页操作更进一步。安逸哈。
carl 21主题204帖子

1272

积分

培训班

发表于 2011-6-21 22:29:55 | 只看该作者

这样操作jQ太方便了,老大辛苦了

这样操作jQ太方便了,老大辛苦了
aardio - 没有做不到的,只有想不到的!
aiwen 3主题52帖子

888

积分

三级会员

Rank: 4

发表于 2011-6-22 09:19:16 | 只看该作者

很强大,我以前也写了个jquery,不过每次需要写个类似wb.doscript('..\jquery.js')才能执行,用了老大的确实方便。不过好像每次执行的时

很强大,我以前也写了个jquery,不过每次需要写个类似wb.doscript('..\jquery.js')才能执行,用了老大的确实方便。不过好像每次执行的时候都要问我是否执行本地js文件的提示,如果是用网络的就没有,不知道为何?

点评

更新版本再试一下  发表于 2011-6-22 12:09
hgbuser 17主题97帖子

750

积分

荣誉会员

Rank: 8Rank: 8

发表于 2011-6-22 11:23:50 | 只看该作者

wb.jQuery,这个好!非常方便,令人心动啊

wb.jQuery,这个好!非常方便,令人心动啊
有太多东西要学,可是感觉没时间。
quicker 30主题700帖子

4203

积分

超级版主

Rank: 8Rank: 8

发表于 2011-9-8 09:54:26 | 只看该作者

[i=s] 本帖最后由 quicker 于 2011-9-8 09:55 编辑 [/i] 此问题在jQuery1.6.3版本已经解决了 [url=htt

本帖最后由 quicker 于 2011-9-8 09:55 编辑

此问题在jQuery1.6.3版本已经解决了

code.jquery.com/jquery-1.6.… Minified version
code.jquery.com/jquery-1.6.… Source version

在最新版本aardio中,
可将jquery-1.6.3.min.js下载放置于工程的以下位置
/res/js/jQuery/jQuery.min.js

下面是标准库中 wb.jQuery函数的源码:

         jQuery = {
            _get = function (){
                var s = owner .waitDoc().Script;
                var jq = s.jQuery
                if (jq)
                     return jq;
               
                owner .loadScript( "/res/js/jQuery/jQuery.min.js" , , "utf-8" );
                 
                if ( ! s.jQuery ){
                     owner .loadScript( "http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" , , "utf-8" );
                     if ( ! s.jQuery )
                         owner .loadScript( "http://code.jquery.com/jquery-1.6.3.min.js" , , "utf-8" );   
                }
                return s.jQuery;
            }
        };
wudijushi 39主题205帖子

1451

积分

四级会员

Rank: 6Rank: 6

发表于 2011-10-21 15:35:16 | 只看该作者

请教一下楼主,我现在也是用easy ui datagrid + sqlite 写一小工具,现在想到的方式是aardio 读取数据,然后生成JSON格式保存文件,

请教一下楼主,我现在也是用easy ui datagrid + sqlite 写一小工具,现在想到的方式是aardio 读取数据,然后生成JSON格式保存文件,然后datagrid 的loadData 读入,不过这样好像不行呢,楼主有好的解决方案吗?
analytys 10主题108帖子

623

积分

三级会员

Rank: 4

 楼主| 发表于 2011-10-31 18:39:47 | 只看该作者

[quote][size=2][color=#999999]wudijushi 发表于 2011-10-21 15:35[/color] [url=forum.

wudijushi 发表于 2011-10-21 15:35
请教一下楼主,我现在也是用easy ui datagrid + sqlite 写一小工具,现在想到的方式是aardio 读取数据,然后 ...

不需要保存成文件,直接生成dom,然后用jquery easyui加载这个dom
enjoy my life !
murphy3847 0主题10帖子

58

积分

一级会员

Rank: 2

发表于 2016-6-15 12:57:59 | 只看该作者

学习了。

学习了。
ayumi502 2主题31帖子

375

积分

二级会员

Rank: 3Rank: 3

发表于 2016-6-17 19:41:25 来自手机 | 只看该作者

新版的jquery 比方法已经失效了

新版的jquery 比方法已经失效了