上传文件的大小

发布于 2024-07-08 12:50:31 字数 85 浏览 5 评论 0原文

将文件上传到服务器时,Web 浏览器是否会在 http 标头中发送文件大小? 如果是这样的话,是否可以仅通过读取标头来拒绝文件,而不等待整个上传过程完成?

Do web browsers send the file size in the http header when uploading a file to the server? And if that is the case, then, is it possible to refuse the file just by reading the header and not wait for the whole upload process to finish?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

女中豪杰 2024-07-15 12:50:32

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

HTTP客户是
鼓励为整个文件输入提供内容长度,以便
繁忙的服务器可以检测建议的文件数据是否太大而无法处理
合理处理

但内容长度不是必需的,因此您不能依赖它。 此外,攻击者还可以伪造错误的内容长度。

读取文件内容是唯一可靠的方法。 话虽如此,如果内容长度存在并且太大,则关闭连接将是合理的做法。

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

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

HTTP clients are
encouraged to supply content-length for overall file input so that a
busy server could detect if the proposed file data is too large to be
processed reasonably

But the content-length is not required, so you cannot rely on it. Also, an attacker can forge a wrong content-length.

To read the file content is the only reliable way. Having said that, if the content-lenght is present and is too big, to close the connection would be a reasonable thing to do.

Also, the content is sent as multipart, so most of the modern frameworks decode it first. That means you won't get the file byte stream until the framework is done, which could mean "until the whole file is uploaded".

编辑:在走得太远之前,您可能需要检查依赖于apache配置的其他答案:使用 jQuery,上传前限制文件大小 . 仅当您确实需要更多自定义反馈时,下面的描述才有用。

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

以下是来自具有 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-Length,此外标头中还有 Content-Type文件部分(每个文件都有自己的标头,这就是多部分编码的目的)。 请注意,浏览器有责任通过猜测文件类型来设置相关的 Content-Type ; 你不能保证它,但对于早期拒绝来说它应该相当可靠(但你最好在整个文件完全可用时检查它)。

现在,有一个问题。 我曾经这样过滤图像文件,不是根据大小,而是根据内容类型; 但是当您想尽快停止请求时,就会出现同样的问题:浏览器只有在整个请求发送后才会收到您的响应,包括表单内容和上传的文件

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

因此,您只想在后台异步检查的情况下使用此方法(使用检查文件字段的计时器)。 所以我有这样的技巧:

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

相当混乱,是吗? 如果你们有更好的选择,我洗耳恭听。

EDIT : before going too far, you may want to check this other answer relying on apache configuration : Using jQuery, Restricting File Size Before Uploading . the description below is only useful if you really need even more custom feedback.

Yes, you can get some information upfront, before allowing the upload of the whole file.

Here's an example of header coming from a form with the enctype="multipart/form-data" attribute :

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 )

You have the Content-Length in the header, and additionally there is the Content-Type in the header of the file part ( each file has its own header, which is the purpose of multipart encoding ). Beware that it's the browser responsibility to set a relevant Content-Type by guessing the file type ; you can't guarantee it, but it should be fairly reliable for early rejection ( yet you'd better check the whole file when it's entirely available ).

Now, there is a gotcha. I used to filter image files like that, not on the size, but on the content-type ; but as you want to stop the request as soon as possible, the same problem arises : the browser only gets your response once the whole request is sent, including form content and thus uploaded files.

If you don't want the provided content and stop the upload, you have no choice but to brutally close the socket. The user will only see a confusing "connection reset by peer" message. And that sucks, but it's by design.

So you only want to use this method in cases of background asynchronous checks ( using a timer that checks the file field ). So I had that hack :

  • I use jquery to tell me if the file field has changed
  • When a new file is chosen, disable all other file fields on the same form to get only that one.
  • Send the file asynchronously ( jQuery can do it for you, it uses a hidden frame )
  • Server-side, check the header ( content-length, content-type, ... ), cut the connection as soon as you got what you need.
  • Set a session variable telling if that file was OK or not.
  • Client-side, as the file is uploaded to a frame you don't even get any kind of feedback if the connection is closed. Your only alternative is a timer.
  • Client-side, a timer polls the server to get a status for the uploaded file. Server side, you have that session variable set, send it back to the brower.
  • The client has the status code ; render it to your form : error message, green checkmark/red X, whatever. Reset the file field or disable the form, you decide. Don't forget to re-enable other file fields.

Quite messy, eh ? If any of you has a better alternative, I'm all ears.

时光病人 2024-07-15 12:50:32
  1. 我不确定,但您不应该真正信任标头中发送的任何内容,因为它可能是用户伪造的。

    我不确定

  2. 这取决于服务器的工作方式。 例如,在 PHP 中,您的脚本只有在文件上传完成后才会运行,因此这是不可能的。

  1. I'm not sure, but you should not really trust anything sent in the header, as it could be faked by the user.

  2. It depends on how the server works. For example in PHP your script will not run until the file upload is complete, so this wouldn't be possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文