关于图片与文本同存在数据库中的具体思路,如何在Form域中Post大于100K字节的数据

以前在工作中遇到一个问题,当表单发送的数据量很大时,就会报错。查阅MSDN了解到,原
因是微软对用Request.Form()可接收的最大数据限制为100K字节。 

一、统一名词 文字框:显示聊天内容的框架页面 
输入框:输入聊天信息的框架页面 
刷新框:自刷新获取最新聊天信息的框架页面,该页面不直接显示出来 
二、如何实现 
实现无刷新,就是要在当前文字框聊天内容后面不断的添加新的聊天信息。 
实现的方式是“添加新信息”,而不是“重新刷新”。 
三、技术要点 
实现像chat.163.com的无闪烁刷新的聊天室要用到的关键代码: 
1.自刷新: 
<meta http-equiv=”refresh” content=”2″>
2.向html文件写代码:
<script>
top.frametext.document.write(“text”); 
</script>
四、例子
1.frame.asp页面。最简单的包含三个框架页
文本框frametext.htm;name=frametext
输入框frameinput.asp;
刷新框framerefresh.asp;
2.文本框frametext.htm内容:
最简单的文本内容。略
3.输入框frameinput.asp内容:

4.刷新框framefresh.asp内容(关键)
……
<%
`此处用代码获取最新的聊天信息
`最新信息保存在数组ArrRecord()
`OutNum参数纪录是否有新的聊天纪录出现 
%>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<meta http-equiv=”refresh” content=”2″><!–定时刷新获取最新信息–> 
…..
<%
if OutNum>0 then `对于用户来讲,如果有新的信息的话,则输出新信息,否则不
输出
response.write “<script language=””javascript””>”
for i = 1 to outnum
response.write “top.frametext.document.write(“””& ArrRecord(i) &”””)
;”
next
response.write “</script>”
end if
%>
….. 
五、相关问题 
1.自刷新存在的一个问题是焦点定位问题(也就是自动滚屏的问题)。用户在文 
本框看到的都是第一次进入chatroom看到的内容的位置,不会自动滚屏到新信息 
的位置,必须滚动滚动栏才可以。 
在chat.163.com,它通过用户点选“自动滚屏”的方法来实现。其实就是选择“ 
自动滚屏”,程序将启用控制文本框滚屏的一个js程序,关键部分为: 
function ScrollWindow() 

….. 
this.scroll(0, 65000); //将文本框scroll到指定的位置。这里选定(0,65000) 
,就是指向最左下角的位置,由于屏幕高度才600不到,所以在一个用户聊天过程 
中,几乎永远不可能达到(0,65000)的位置。这样就保证了屏幕永远滚到最底层。 
setTimeout(’scrollWindow();’,200); //循环。否则只滚动一次是没用的 

2.清屏。如果不清屏,一直开着聊天窗口,文本框文字内容将永无止境的增加。 
清屏可以通过reload 文本框页面的方法实现。

关于图片与文本同存在数据库中的具体思路

微软建议用Request.BinaryRead()读取表单数据,但由于这种方法读出的是二进制数据,需
要对读出的数据逐字节进行分析,生成有意义的字符串(MSDN上的一段程序就是这样写的,
但它并没有考虑诸如标点符号等转义字符需要进行特殊分析)。如果说这种方法对于纯英文
系统勉强可用的话,则对于中文系统来说就有极大的麻烦,因为汉字是用两个字节表示的,
而读出的二进制数据本身并不能判断是英文还是汉字(否则就不是二进制数据,而是字符串
了^-^)。这样的话就必须了解汉字的编码规律才能进行分析。最后,即使算法上能把这些
都分析出来,大家想想对于一个MB级的巨型字符串逐字节进行分析,其效率何如?所以,此
路不通!

首先,你的表单的类型设为 <FORM ENCTYPE=”multipart/form-data”
ACTION=”uploadresult.asp” METHOD=POST>

不过,办法总是有的。一开始我以为是整个表单数据的总和不能超过100KB,后来发现这是
对表单内每个域的限制。问题的解决办法是,对于一个需要发送大数据的域,在提交表单前
将数据拆分为小于限额的数份,分别放在数个hidden域中,同时把原有域清空,再正式提交
表单。服务器端还是用Request.Form()读取各hidden域的数据,再按照顺序把他们拼接起来
就行了。主要代码如下:

Please choose a picture to upload:
<INPUT NAME=”picture” TYPE=FILE ACCEPT=”image/*”>
<input name=”text1″ type=text >
</form>
然后在下一页,用分离的办法先分出文本,此时不能用request.form,应变为
FormData = Request.BinaryRead( FormSize )

注意:需要在Form中的HTML代码内指定一个DIV,以便向其中动态插入hidden域。

FormSize = Request.TotalBytes
bnCRLF = chrB( 13 ) & chrB( 10 )
Divider = LEFTB( FormData, INSTRB( FormData, bnCRLF ) – 1 )
DataStart = INSTRB( FormData, bnCRLF & bnCRLF ) + 4 
DataEnd = INSTRB( DataStart + 1, FormData, divider ) – DataStart
Response.ContentType = “image/gif”
Response.BinaryWrite MIDB( FormData, DataStart, DataEnd )

====客户端示例代码====
<script language=javascript>
//数据拆分,并放到相应的hidden域中,在Form的onSubmit事件中激发
function fnPreHandle()
{
var iCount; //拆分为多少个域
var strData; //原始数据
var iMaxChars = 50000;//考虑到汉字为双字节,域的最大字符数限制为50K
var iBottleNeck = 2000000;//如果文章超过2M字,需要提示用户
var strHTML;

这里先分出的是图像
然后在将其二进制转换为文本。

//原始数据 
strData = frmTest.BigField.value;

求出大小。

发表评论