分类：电脑/网络-互联网
问题：asp提交表单包括图片的代码提交表单包括图片的代码怎么办啊？如果 
提交表单包括图片的怎么办啊？如果能给我同时两张的图片代码更好了。大家帮帮我，满分相赠
回答：朋友您好！！！asp无组件上传的原理 一、无组件上传的原理 我还是一点一点用一个实例来说明的吧，客户端HTML如下。要浏览上传附件，我们通过<input type="file">元素，但是一定要注意必须设置form的enctype属性为"multipart/form-data"： <form method="post" action=" p" enctype="multipart/form-data"> <label> <input type="file" name="file1" /> </label>  <input type="text" name="filename" value="default filename"/>  <input type="submit" value="Submit"/> <input type="reset" value="Reset"/> </form> 在后台asp程序中，以前获取表单提交的ASCII 数据，非常的容易。但是如果需要获取上传的文件，就必须使用Request对象的BinaryRead方法来读取。BinaryRead方法是对当前输入流进行指定字节数的二进制读取，有点需要注意的是，一旦使用BinaryRead 方法后，再也不能使用Request.Form 或 Request.QueryString 集合了。结合Request对象的TotalBytes属性，可以将所有表单提交的数据全部变成二进制，不过这些数据都是经过编码的。首先让我们来看看这些数据是如何编码的，有无什么规律可循，编段代码，在代码中我们将BinaryRead读取的二进制转化为文本，输出出来，在后台的 p中（注意该示例不要上传大文件，否则可能会造成浏览器死掉）： <% Dim biData, PostData Size = Request.TotalBytes biData = Request.BinaryRead(Size) PostData = BinaryToString(biData,Size) Response.Write "" '使用pre，原样输出格式 ' 借助RecordSet将二进制流转化成文本 Function BinaryToString(biData,Size) Const adLongVarChar = 201 Set RS = createObject("ADODB.Recordset") RS.Fields.Append "mBinary", adLongVarChar, Size RS.Open RS.AddNew RS("mBinary").AppendChunk(biData) RS.update BinaryToString = RS("mBinary").Value RS.Close End Function %> 简单起见，上传一个最简单的文本文件(G:\homepage.txt，内容为"宝玉： ")来试验一下，文本框filename中保留默认值"default filename"，提交看看输出结果： -----------------------------7d429871607fe Content-Disposition: form-data; name="file1"; filename="G:\homepage.txt" Content-Type: text/plain 宝玉：  -----------------------------7d429871607fe Content-Disposition: form-data; name="filename" default filename -----------------------------7d429871607fe-- 可以看出来对于表单中的项目，是用过"-----------------------------7d429871607fe"这样的边界来分隔成一块一块的，每一块的开始都有一些描述信息，例如：Content-Disposition: form-data; name="filename"，在描述信息中，通过name="filename"可以知道表单项的name。如果有filename="G:\homepage.txt"这样的内容，说明是一个上传的文件，如果是一个上传的文件，那么描述信息会多一行Content-Type: text/plain来描述文件的Content-Type。描述信息和主体信息之间是通过换行来分隔的。 嗯，基本上清晰了，根据这个规律我们就知道该怎么来分离数据，再对分离的数据进行处理了，不过差点忽略一个问题，就是边界值(上例中的"-----------------------------7d429871607fe")是怎么知道的？每次上传这个边界值是不一样的，还好还好asp中可以通过Request.ServerVariables( "HTTP_CONTENT_TYPE")来获之，例如上例中HTTP_CONTENT_TYPE内容为："multipart/form-data; boundary=---------------------------7d429871607fe"，有了这个，我们不仅可以判断客户端的form中有无使用enctype="multipart/form-data"(如果没有使用，那么下面就没必要执行啦)，还可以获取边界值boundary=---------------------------7d429871607fe。（注意：这里获取的边界值比上面的边界值开头要少"--"，最好补充上。） 至于如何分析数据的过程我就不多赘述了，无非就是借助InStr,Mid等这样的函数来分离出来我们想要的数据。 二、分块上传，记录进度 要实时反映进度条，实质就是要实时知道当前服务器获取了多少数据？再回想一下我们实现上传的过程，我们是通过Request.BinaryRead(Request.TotalBytes)来实现的，在Request的过程中我们无法得知当前服务器获取了多少数据。所以只能通过变通的方法了，如果我们可以将获取的数据分成一块一块的，然后根据已经上传的块数我们就可以算出来当前上传了多大了！也就是说，如果我1K为1块，那么上传1MB的输入流就分成1024块来获取，例如我当前已经获取了100块，那么就表明当前上传了100K。当我提出分块的时候很多人觉得不可思议，因为他们都忽略BinaryRead方法不仅是可以读取指定大小，而且可以连续读取的。 写个例子来验证一下分块读取的完整性，在刚才的例子基础上（注意该示例不要上传大文件，否则可能会造成浏览器死掉）： <% Dim biData, PostData, TotalBytes, ChunkBytes ChunkBytes = 1 * 1024 ' 分块大小为1K TotalBytes = Request.TotalBytes ' 总大小 PostData = "" ' 转化为文本类型后的数据 ReadedBytes = 0 ' 初始化为0 ' 分块读取 Do While ReadedBytes < TotalBytes biData = Request.BinaryRead(ChunkBytes) ' 当前块 PostData = PostData & BinaryToString(biData,ChunkBytes) ' 将当前块转化为文本并拼接 ReadedBytes = ReadedBytes + ChunkBytes ' 记录已读大小 If ReadedBytes > TotalBytes Then ReadedBytes = TotalBytes Loop Response.Write "" ' 使用pre，原样输出格式 ' 将二进制流转化成文本 Function BinaryToString(biData,Size) Const adLongVarChar = 201 Set RS = createObject("ADODB.Recordset") RS.Fields.Append "mBinary", adLongVarChar, Size RS.Open RS.AddNew RS("mBinary").AppendChunk(biData) RS.update BinaryToString = RS("mBinary").Value RS.Close End Function %> 试验一下上传刚才的文本文件，输出结果证明这样分块读取的内容是完整的，并且在While循环中，我们可以在每次循环时将当前状态记录到Application中，然后我们就可以通过访问该Application动态获取上传进度条。 另：上例中是通过字符串拼接的，如果是要拼接二进制数据，可以通过ADODB.Stream对象的Write方法，示例代码如下： Set bSourceData = createobject("ADODB.Stream") bSourceData.Open bSourceData.Type = 1 'Binary Do While ReadedBytes < TotalBytes biData = Request.BinaryRead(ChunkBytes) bSourceData.Write biData ' 直接使用write方法将当前文件流写入bSourceData中 ReadedBytes = ReadedBytes + ChunkBytes If ReadedBytes > TotalBytes Then ReadedBytes = TotalBytes Application("ReadedBytes") = ReadedBytes Loop 三、保存上传的文件 通过Request.BinaryRead获取提交数据，分离出上传文件后，根据数据类型的不同，保存方式也不同： 对于二进制数据，可以直接通过ADODB.Stream对象的SaveToFile方法，将二进制流保存成为文件。 对于文本数据，可以通过TextStream对象的Write方法，将文本数据保存到文件中。 对于文本数据和二进制数据，是可以方便的相互转换的，对于上传小文件来说，两者基本上没什么差别。但是两种方式保存时还是有一些差别的，对于ADODB.Stream对象，必须将所有数据全部装载完才可以保存成文件，所以使用这种方式如果上传大文件将很占用，而对于TextStream对象，可以在文件创建好后，一次Write一部分，分多次Write，这样的好处是不会占用服务器内存空间，结合上面分析的分块获取数据原理，我们可以每获取一块上传数据就将之Write到文件中。我曾做过试验，同样本机上传一个200多MB的文件，使用第一种方式内存一直在涨，到最后直接提示计算机虚拟内存不足，最可恨是即使进度条表示文件已经上传完，但是最终文件还是没有保存上。而使用后一种方法，上传过程中内存基本上无什么变化。 四、未解决的难题 我在博客园上看到Bestcomy描述他的Asp.Net上传组件是可以和Sever.SetTimeOut无关的，而在Asp中我是没能做到，对于上传大文件，就只有将Server.SetTimeOut设置为一个很大的值才可以。不知道有没有比较好的解决方法。 如果我们在保存文件时，使用TextStream对象的Write方法，那么如果用户上传时中断了文件传输，已经上传的那部分文件还是在的，如果可以断点续传就好了。关键问题是Request.BinaryRead方法虽然可以分块读取，但是却不能跳过某一段读取！ 祝您愉快！！！