Make writing a habit together! This is the second day of my participation in the “Gold Digging Day New Plan · April More text challenge”. Click here for more details.
What are the ways to upload files on the Web? May be a lot of people do not understand, in order to let you know more, xiaobian summed up the following content for you, I hope you can harvest according to this article.
Uploading files is a common requirement for Web development. Uploading files requires a file input field. If you add a multiple attribute to the file input field, you can select multiple files at once (unsupported browsers will automatically ignore this attribute).
<input multiple type="file">
Copy the code
Click the input box to open the Browse file dialog box and select files. Generally, one input box will do just fine. To upload multiple files, you can also use multiple input boxes
Basic Upload Mode
When you put the file input field into the form, you can submit the selected file to the server when submitting the form. Note that since the submitted form contains files, you need to change the encType attribute of the form element to multipart/form-data
<form action="#" enctype="multipart/form-data" method="post">
<input name="file" type="file">
<button type="submit">Upload</button>
</form>
Copy the code
This upload method is traditional synchronous upload. If the uploaded file is large, it usually needs to wait for a long time. After the upload is complete, the page will be reloaded, and the operation can be continued only after the upload is complete
Early browsers did not support asynchronous uploads, but you could use iframe to simulate them by hiding an element in a page, specifying a name value, and associating the element’s target attribute with the value of the element’s name attribute
<form action="#" enctype="multipart/form-data" method="post" target="upload-frame">
<input name="file" type="file">
<button type="submit">Upload</button>
</form>
<iframe id="upload-frame" name="upload-frame" src="about:blank" style="display: none;"></iframe>
Copy the code
This way, when the form is submitted for upload, the page is not reloaded. Instead, the iframe is reloaded, but the iframe is hidden and is not perceived by the reload
Access to the file
The File API provides the ability to access files through the files property of the input field. This will result in a FileList. This is a set of names
var input = document.querySelector('input[type="file"]')
var file = input.files[0]
console.log(file.name) // File name
console.log(file.size) // File size
console.log(file.type) // File type
Copy the code
Browsers that support the File API can refer to Caniuse
Ajax upload
Since you can access the File content directly through the File API, you can upload the File directly with the XMLHttpRequest object by passing it as a parameter to the SEND method of the XMLHttpRequest object
var xhr = new XMLHttpRequest()
xhr.open('POST'.'/upload/url'.true)
xhr.send(file)
Copy the code
FormData is a constructor that creates a new instance and then adds data to it through the append method of the instance, adding the uploaded file directly to it
var formData = new FormData()
formData.append('file', file, file.name) // The third argument is the file name
formData.append('username'.'Mary') // Additional parameters can also be added
Copy the code
You can even take form elements directly as instantiation parameters so that the entire form’s data is included
var formData = new FormData(document.querySelector('form'))
Copy the code
Once the data is ready, it is uploaded, again as a parameter to the SEND method of the XMLHttpRequest object
var xhr = new XMLHttpRequest()
xhr.open('POST'.'/upload/url'.true)
xhr.send(formData)
Copy the code
Monitor upload progress
The XMLHttpRequest object also provides a progress event based on which you can tell how well the upload is progressing
var xhr = new XMLHttpRequest()
xhr.open('POST'.'/upload/url'.true)
xhr.upload.onprogress = progressHandler // This function is defined next
Copy the code
The uploaded progress event is triggered by the xhr.upload object, whose loaded and total properties are used in the event handler to calculate the progress of the upload
function progressHandler(e) {
var percent = Math.round((e.loaded / e.total) * 100)}Copy the code
The above calculation results in a number representing the percentage of completion, although these two values may not always be present, so be sure to determine the lengthComputable attribute of the event object first
function progressHandler(e) {
if (e.lengthComputable) {
var percent = Math.round((e.loaded / e.total) * 100)}}Copy the code
Browsers that support Ajax uploads can be found at caniuse caniuse.com/#feat=xhr2
Segmentation upload
Using the slice method of a File object, you can slice a File by passing two arguments, a start and an end, which will return a new Blob object containing the portion of the original File from the start to the end. This can be determined by file instanceof Blob, which is the parent of file.)
var blob = file.slice(0.1024) // File from byte position 0 to byte position 1024 that 1KB
Copy the code
Large files can be split into several Blob objects and uploaded separately
function upload(file) {
let formData = new FormData()
formData.append('file', file)
let xhr = new XMLHttpRequest()
xhr.open('POST'.'/upload/url'.true)
xhr.send(formData)
}
var blob = file.slice(0.1024)
upload(blob) // Upload the first part
var blob2 = file.slice(1024.2048)
upload(blob2) // Upload the second part
// Upload the rest
Copy the code
It’s usually more convenient to use a loop
var pos = 0 // Start position
var size = 1024 // Block size
while (pos < file.size) {
let blob = file.slice(pos, pos + size) // End position = start position + block size
upload(blob)
pos += size // Continue the split from the end position next time
}
Copy the code
The code that the server receives in chunks for reassembly is not shown here
Uploading files in this way will send multiple HTTP requests at once. How do you handle the situation where multiple requests are sent simultaneously? There are a number of methods that you can use to handle a Promise, make each upload return a Promise object, and then combine them with the promise. all method, which takes an array as an argument, So put the Promise objects returned from each upload in an array
var promises = []
while (pos < file.size) {
let blob = file.slice(pos, pos + size)
promises.push(upload(blob)) // upload should return a promise
pos += size
}
Copy the code
Also modify the upload function to return a promise
function upload(file) {
return new Promise((resolve, reject) = > {
let formData = new FormData()
formData.append('file', file)
let xhr = new XMLHttpRequest()
xhr.open('POST'.'/upload/url'.true)
xhr.onload = () = > resolve(xhr.responseText)
xhr.onerror = () = > reject(xhr.statusText)
xhr.send(formData)
})
}
Copy the code
When it’s all done
Promise.all(promises).then((response) = > {
console.log('Upload success! ')
}).catch((err) = > {
console.log(err)
})
Copy the code
Browsers that support file splitting can refer to Caniuse
Checking whether the file object has the method will tell you whether the browser supports it or not. For earlier versions of some browsers, the corresponding browser vendor prefix is required
var slice = file.slice || file.webkitSlice || file.mozSlice
if (slice) {
let blob = slice.call(file, 0.1024) // call
upload(blob)
} else {
upload(file) // Upload the entire file directly without partition support, or the file is too large
}
Copy the code
Drag and drop to upload
The drag-and-drop API enables drag-and-drop file uploads. By default, dragging and dropping a file to the browser will attempt to open the file. To use drag-and-drop, you need to prevent this default behavior
document.addEventListener('dragover'.function(e) {
e.preventDefault()
e.stopPropagation()
})
Copy the code
Specify any element as the drop area, and bind the drop event to an element
var element = document.querySelector('label')
element.addEventListener('drop'.function(e) {
e.preventDefault()
e.stopPropagation()
// ...
})
Copy the code
The file is retrieved from the dataTransfer property of the event object and then uploaded
var file = e.dataTransfer.files[0]
upload(file) The // upload function has been defined previously
Copy the code
Choose the type
Add the Accept attribute to the file input box to specify the type of file to be selected. For example, if you want to select a PNG image, specify the value image/ PNG, or if you want to allow all types of images, image/*
<input accept="image/*" type="file">
Copy the code
Capture =”camera” : capture=”camera” : capture=”camera” : Capture =”camera” : Capture =”camera” : Capture =”camera” : Capture =”camera
if (iOS) { // iOS use navigator.userAgent
input.removeAttribute('capture')}Copy the code
Unsupported browsers automatically ignore these properties
Custom styles
File input fields look different from browser to browser, and styling your input is not always easy. If you need to apply a custom style, a trick is to attach a label element to the file input field. Clicking on the label element triggers the file input field to click. Open the browse file dialog box, equivalent to clicking the file input box effect
<label for="file-input"></label>
<input id="file-input" style="Clip: the rect (0,0,0,0); position: absolute;" type="file">
Copy the code
At this point, you can hide the original file input field and style the label element any way you want. After all, styling the label element is much easier than styling the input element
After reading the above content, do you have any further understanding of how the Web implements file uploading? If you want to know more about the content, welcome to pay attention to the Cloud industry information channel, thank you for reading.