Recently, WHEN I was dealing with a node file upload problem, I encountered a great obstacle. Finally, I checked a lot of information and asked the big guy to solve it. This prompted me to make this part completely clear, the next time I encounter can not look up information everywhere to solve the problem
Content-type Basic concept
Content-type is the HTTP entity header that indicates the MIME Type of the resource. It can appear in either the request header or the response header.
- In the request header, the client tells the server what type of data to send, so that the server knows how to properly process the data.
- In the response header, the server tells the client the type of the response data to be returned, and the client (browser) processes it based on the MIME type, or the developer processes it himself.
Content-type is written in a format similar to the following
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something
Copy the code
The value part consists of three main parts
- Mimetype (MIME type of resource or data)
- Charset (character set)
- Boundary (content boundary, useful for multiple types of content)
Between parts; Segmentation, which MIME types are many, the following mainly said that we commonly used several
Content-Length
The most common one with content-type is content-length
Content-length specifies the Length of eight bytes. If content-length is present and valid, the value must be correct, otherwise unexpected errors will occur.
- Content-length larger than the actual Length may result in no response (the client or server waits for the next byte to be read and fails to read it)
- Content-length may truncate data if it is smaller than the actual Length
Content-type is applied to the response
Common content-types in responses are:
application/json
Ajax request data returns JSONapplication/javascript
Javascript filestext/css
CSS file (note that unlike JS, this is text, application usually represents executable or parsed binary data)text/html
The HTML filetext/plain
Plain text
Content-type is applied to the request
Requests to send data use POST requests, such as those sent to a form, and the content-Type is usually used
application/x-www-form-urlencoded
Application/X-www-form-urlencoded data will be coded. For non-alphanumeric characters, percent-encoding is performed. Special characters are expressed in ASCII hexadecimal format followed by %, and whitespace is expressed as + or %20
POST / HTTP / 1.1
Host: test.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 19
name=xiaoming&age=8
Copy the code
application/json
Application/JSON is also used a lot now in request headers, where the high-speed server sends a JSON string
POST / HTTP / 1.1
Host: test.com
Content-Type: application/json
Content-Length: 22
{"name": "xiaoming"."age": 8}
Copy the code
multipart/form-data
Multipart /form-data is usually used when the form needs to be passed to the file, because the file needs to be represented in binary mode
POST/test. HTTP / 1.1 HTMLHost: test.com
Content-Type: multipart/form-data; boundary="boundary" --boundaryContent-Disposition: form-data; name="name1"
value1
--boundary
Content-Disposition: form-data; name="name2"
value2
Copy the code
File upload
Upload in browser
File uploads in the browser require the construction of a FormData object, and the data is added to the FormData object using append. The File is usually of type File or BLOB. Once the FormData is constructed, pass it in via the request API, and the content-Type and Content-Length browser client will set it automatically
const file = new File(["foo"]."foo.txt", {
type: "text/plain",})const form = new FormData()
form.append('name'.'xiaoming')
form.append('file', file, 'text.png')
form.append('age'.8)
const xhr = new XMLHttpRequest()
xhr.open('POST'.'http://test.com/test/upload')
xhr.send(form)
Copy the code
The request reads like this
POST HTTP / 1.1 / test/uploadHost: test.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryYr963ldXs1XPBv7A
------WebKitFormBoundaryYr963ldXs1XPBv7A
Content-Disposition: form-data; name="name"
xiaoming
------WebKitFormBoundaryYr963ldXs1XPBv7A
Content-Disposition: form-data; name="file"; filename="text.png"
Content-Type: text/plain
foo
------WebKitFormBoundaryYr963ldXs1XPBv7A
Content-Disposition: form-data; name="age"
8
------WebKitFormBoundaryYr963ldXs1XPBv7A--
Copy the code
The Node in the upload
So what do you do if you want to upload like a browser in Node? Node does not have FormData objects, so we can use the third-party form-data package
const FormData = require('form-data')
const fs = require('fs')
const mime = 'image/png'
const form = new FormData()
form.append('name'.'xiaoming')
form.append('file', fs.createReadStream('/foo/bar.png'), {
contentType: mime,
filename: 'test.png'
})
form.append('age'.8)
// Get the content length
const length = await new Promise((resolve, reject) = > {
data.getLength((err, length) = > {
if (err) {
reject(err)
} else {
resolve(length)
}
})
})
// Here we use axios to send the request, which would be the same in any library. The main thing is to set 'content-type' and 'content-Length' correctly
const headers = data.getHeaders()
const res = await axios
.post(pssConfig.uploadLink, data, {
responseType: 'json'.headers: {
'Content-Type': headers['content-type'].'Content-Length': length
}
})
Copy the code
conclusion
Thank you for your patience. I hope I can correct a lot of bad things. Often we ignore the seemingly simple things, but the importance of these basics is revealed when we actually use them. But the most important, whether it is to check information or ask others, after solving the problem should be timely thinking and summary to become their own things
Thank you for your support
Posts will sync with Github and Blog
And recently opened a new public account, will continue to share their own ideas, keep updated, hope to have more exchanges with you ~