Pure Node.js file upload (multipart POST) without using a framework

后端 未结 3 855
半阙折子戏
半阙折子戏 2021-01-18 05:32

The third-party libraries \"node-formidable\" and \"express\" come with the ability to handle multipart POST requests (e.g. with a file upload form), but I don\'t want to us

3条回答
  •  盖世英雄少女心
    2021-01-18 06:05

    Just to clarify because it seems some people are angry that the other answer didn't help much: There is no simple way of doing this without relying on a library doing it for you.

    First, here's an answer to another question trying to clarify what happens on a POST file upload: https://stackoverflow.com/a/8660740/2071242

    To summarize, to parse such an upload, you'll first need to check for a Content-Type header containing "multipart/form-data" and, if one exists, read the boundary attribute within the header.

    After this, the content comes in multiple parts, each starting with the boundary string, including some additional headers and then the data itself after a blank line. The browser can select the boundary string pretty freely as long as such byte sequence doesn't exist in the uploaded data (see the spec at http://tools.ietf.org/html/rfc1867 for details). You can read in the data by registering a callback function for the request object's data event: request.on('data', callback);

    For example, with boundary "QweRTy", an upload might look something like this:

    POST /upload HTTP/1.1
    (some standard HTTP headers)
    Content-Type: multipart/form-data; boundary=QweRTy
    
    --QweRTy
    Content-Disposition: form-data; name="upload"; filename="my_file.txt"
    Content-Type: text/plain
    
    (The contents of the file)
    --QweRTy--
    

    Note how after the initial headers two dashes are added to the beginning of each boundary string and two dashes are added to the end of the last one.

    Now, what makes this challenging is that you might need to read the incoming data (within the callback function mentioned above) in several chunks, and there are no guarantees that the boundary will be contained within one chunk. So you'll either need to buffer all the data (not necessarily a good idea) or implement a state machine parser that goes through the data byte by byte. This is actually exactly what the formidable library is doing.

    So after having similar considerations, what I personally decided to do is to use the library. Re-implementing such a parser is pretty error-prone and in my opinion not worth the effort. But if you really want to avoid any libraries, checking the code of formidable might be a good start.

提交回复
热议问题