鸟食轩

 Microsoft .NET[C#] MVP 2003
随笔 - 429, 文章 - 235, 评论 - 5527, 引用 - 356
数据加载中……

模态窗口对字符串参数的巨无聊限制

    由于IE在对象及对象引用的回收上有不少的问题,我一般很忌讳在不同的窗口和Frame之间传递脚本对象。一般情况下我都是用简单类型来传递参数,比如数字和字符串。对于复杂对象先序列化字符串再在窗口和Frame之间传递,一直以来都挺好的,也没有什么遇到什么问题。

    前几天Tester Team发现一个非常诡异的bug,在模态窗口里的显示的一些数据,当数据量大了后就会出现不确定的错误。开始以为是程序逻辑上的问题,后来调试了半天,发现原来是Modal Dialog的一个特性搞出来的。对于showModalDialog,其参数列表为:

Syntax
    vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])

Parameters
sURL Required. String that specifies the URL of the document to load and display.
vArguments Optional. Variant that specifies the arguments to use when displaying the document. Use this parameter to pass a value of any type, including an array of values. The dialog box can extract the values passed by the caller from the dialogArguments property of the window object.

    MSDN的下面还有一个让人巨郁闷的remark:(
    The vArguments parameter can be referenced within the modal dialog box using the dialogArguments property of the window object. If the vArguments parameter is defined as a string, the maximum string length that can be passed to the modal dialog box is 4096 characters; longer strings are truncated.

    这下知道了,原来是字符串参数太长,被IE自动截断了

    问题是清楚了,可是微软对模态窗口的这个限制是不是太无聊了点啊?不知道微软在搞什么飞机。

    解决这个问题,如果按MSDN说的,我们把vArguments弄成object或array就行了。那么对于参数传出和传入的地方都需要修改"接口"的代码,好麻烦的说。那么能不能让字符串参数突破vArguments的4096个字符的限制呢?

    其实对于一个字符串,只要我们把它包装(有点像C#的Boxing了)成string object,就可以不受vArguments长度的限制了,而且在Modal Dialog中处理字符串的接口函数不需要做任何的修改。比如我们要传递一个5001个字符的字符串,示例如下:
<button onclick="pop()">pop</button>
<script language="javascript">
function pop()
{
    
var str = '';
    for ( var i=0 ; i < 5000 ; ++i )
    
{
        str 
+= 'a';
    }

    
// alert(str.length);
    window.showModalDialog('pop.htm', new String(str+'b'));
}

</script>

    就这样使用一个简单的 new String(str+'b') 就完全突破限制了

posted on 2005-08-27 16:58 birdshome 阅读(3920) 评论(16)  编辑 收藏 网摘 所属分类: Jscript&Dhtml开发

评论

#1楼    回复  引用    

没遇到过这样的问题,今天受教了,呵呵
2005-08-27 17:35 | exhjw [未注册用户]

#2楼    回复  引用    

这是因为object的参数是传了一个引用,而不是传了一个值过去,通过object传参数,真正的值还在原窗口中。4096的限制我想是因为IE中对get形式的url的限制,url的长度不能超过4K,我想那个参数在内部传输的时候应该是附加到url上的。
2005-08-27 17:42 | ocean [未注册用户]

#3楼 [楼主]   回复  引用  查看    

@ocean兄
url + querystring的限制好像是2k吧?我再去查查看。
2005-08-27 17:46 | birdshome      

#4楼    回复  引用  查看    

window.dialogArguments 应该是在客户端 browser 端传递
window.dialogArguments 传递应该不占用那些 get/url/querystring 限制!
当然那个 ModalDialog 的页面本身还是要从服务器下载!

noname1.html
<META NAME="Generator" CONTENT="EditPlus">
</HEAD>
<SCRIPT>
function ShowModalDialog()
{
var o = new Object();
o.Property1 = t1.value;
o.Property2 = t2.value;
window.showModalDialog("noname2.html", o);
}
</SCRIPT>
<BODY>
<BUTTON onclick="ShowModalDialog();">showModalDialog</BUTTON>
<BR>
<INPUT TYPE="text" NAME="t1" VALUE="playyuer">
<BR>
<INPUT TYPE="text" NAME="t2" VALUE="Microshaoft">
</BODY>
</HTML>

noname2.html
<HTML>
<HEAD>
<SCRIPT>
var o = window.dialogArguments;
</SCRIPT>
<title>Untitled</title>
</head>
<BODY>
<SCRIPT>
document.write(o.Property1);
document.write("<br>")
document.write(o.Property2);
</SCRIPT>
</BODY>
</HTML>
2005-08-27 21:01 | Microshaoft      

#5楼    回复  引用  查看    

另外再发个牢骚:
这个 showModalDialog 上的叶面show 出来不能鼠标选择文本,C&P

大家如何解决?
2005-08-27 21:06 | Microshaoft      

#6楼 [楼主]   回复  引用  查看    

@Microshaoft
嗯,确实应该和url、querystring啥的没有关系。但我也查了一下,url+querystring的限制是2k,不是4k。
关于要Copy&Paste模态窗口的内容,除非自己用脚本写好方法,好像没有简单的方法。另外也可以考虑使用SnagIt一类的capture工具。
2005-08-27 21:18 | birdshome      

#7楼    回复  引用  查看    

我的不完全解决方案:
请大家帮我彻底搞定:
save as noname1.html
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<BODY>
<BUTTON onclick="window.showModalDialog('noname1.html')">showModalDialog</button>
<div contentEditable="true"
onkeypress="return false"
onkeydown="return false"
STYLE = "ime-mode:active">
可以选文本!<BR>
随便敲键盘吧<BR>
(但是有输入法呼出的时候还是把文本敲进去了
<BR> HTML: { ime-mode : sMode }
<BR> Scripting: object.style.imeMode [ = sMode ]
<BR>C&P 应该可以在 onkeypress/onkeydown 中实现!
</div>
</BODY>
</HTML>
2005-08-27 21:37 | Microshaoft      

#8楼    回复  引用  查看    

To Microshaoft: 这个问题却是很不~
2005-08-29 11:13 | Boler Guo      

#9楼 [楼主]   回复  引用  查看    

@Microshaoft
由于MSPY的事件处理方式,使得要想屏蔽它的输入基本上很难。而且就选元素都editable了,还是不能随便选取,都会受制于容器自身,好郁闷的说。
2005-08-29 11:19 | birdshome      

#10楼    回复  引用    

传对象
2005-09-07 13:25 | dd [未注册用户]

#11楼 [楼主]   回复  引用  查看    

     传对象确实是可以避免一些问题,可是在模态窗口之间传递对象,同样也不是放之四海而皆准的通用方法。比如模态窗口将其内部生成的对象作为参数回传,传到其parent窗口后,调用该对象的成员方法,将会出"Unexpected call to method or property access."错误(中文好像描述为:灾难性故障)。
2005-09-08 23:44 | birdshome      

#12楼    回复  引用    

学习了,下午学了好多东西
2005-11-24 16:19 | Nameless [未注册用户]

#13楼    回复  引用  查看    

实际上当真正要传送那么多字符串的时候你想一想是不是可以变通一下?如果通过改进程序来解决问题的话岂不是更好?什么情况下需要传送那么多字符串?
2005-11-25 10:57 | 飞行石      

#14楼 [楼主]   回复  引用  查看    

@飞行石
当在一个数据传递不受限制的环境里,虽然大多数情况下传递数据的数量远小于4096,但也总是有能超过4096个字符限制的时候。
2005-11-25 11:17 | birdshome      

#15楼    回复  引用    

强,一定要顶
2006-02-15 11:30 | chuanzai [未注册用户]

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接:

历史上的今天:
2004-08-27 我做的一个SQL -> C# AutoCode