2008-11-11 147 views
11

将文件上传到服务器时,Web浏览器是否将http头中的文件大小发送出去?如果是这种情况,那么是否可以通过阅读标题来拒绝文件,而不是等待整个上传过程完成?上传文件的大小

回答

11

http://www.faqs.org/rfcs/rfc1867.html

HTTP客户端 鼓励提供内容长度的整体文件的输入,这样,如果所提出的文件数据太大,无法 处理合理

一个 繁忙的服务器可以检测

但内容长度不是必需的,所以你不能依赖它。另外,攻击者可能伪造错误的内容长度。

阅读文件内容是唯一可靠的方法。话虽如此,如果content-lenght存在并且太大,关闭连接将是一件合理的事情。

此外,内容以多部分形式发送,所以大多数现代框架都先解码。这意味着在框架完成之前你不会得到文件字节流,这可能意味着“直到整个文件被上传”。

1
  1. 我不知道,但你真的不应该信任标头中发送任何东西,因为它可以由用户来伪造。

  2. 这取决于服务器的工作方式。例如在PHP中,你的脚本不会运行,直到文件上传完成,所以这是不可能的。

2

编辑:之前太过分了,你可能想检查这个依赖于Apache配置的其他答案:Using jQuery, Restricting File Size Before Uploading。以下说明仅在您需要更多自定义反馈时才有用。

是的,您可以在允许上传整个文件之前预先获得一些信息。

这里的头从一种形式来与enctype="multipart/form-data"属性的例子:

POST/HTTP/1.1 
Host: 127.0.0.1:8000 
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.7,fr-be;q=0.3 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Content-Type: multipart/form-data; boundary=---------------------------886261531333586100294758961 
Content-Length: 135361 

-----------------------------886261531333586100294758961 
Content-Disposition: form-data; name=""; filename="IMG_1132.jpg" 
Content-Type: image/jpeg 

(data starts here and ends with -----------------------------886261531333586100294758961) 

你必须在头中的内容长度,另外还有就是内容类型的文件部分的标题(每个文件都有自己的头,这是多部分编码的目的)。请注意,通过猜测文件类型来设置相关的Content-Type是浏览器的责任;你不能保证它,但它应该是相当可靠的早期拒绝(但你最好检查整个文件,当它是完全可用的)。

现在,有一个问题。我曾经像这样过滤图像文件,不是大小,而是内容类型;但是如果您想尽快停止请求,则会出现同样的问题:浏览器在发送完整请求后才会收到您的回复,其中包括表单内容以及上传文件

如果你不想提供的内容并停止上传,你别无选择,只能粗暴地关闭套接字。用户只会看到一个令人困惑的“由对等方重置连接”消息。这很糟糕,但它是有设计的。

所以你只想在后台异步检查的情况下使用这种方法(使用检查文件字段的计时器)。所以我有这样的黑客:

  • 我使用jQuery来告诉我,如果该文件中的字段已经改变
  • 当选择一个新的文件,禁用相同的形式上的所有其他文件字段只得到一个。
  • 将文件发送异步(jQuery的可以为你做它,它使用一个隐藏帧)
  • 服务器端,检查头(内容长度,内容类型,...),一旦切断连接因为你有你需要的东西。
  • 设置一个会话变量,告诉该文件是否正确。
  • 客户端,因为文件上传到一个框架如果连接关闭甚至没有任何反馈。你唯一的选择是计时器。
  • 客户端,定时器轮询服务器以获取上传文件的状态。服务器端,你有该会话变量集,将其发送回浏览器。
  • 客户端有状态码;呈现给你的表单:错误信息,绿色复选标记/红色X,无论如何。重置文件字段或禁用表单,您决定。不要忘记重新启用其他文件字段。

很乱,呃?如果你们中的任何一个人有更好的选择,我全都是耳朵。