These links
– 01 Simple drag-and-drop uploads and progress bars
V1.3: File type verification
In the previous article, we implemented a basic file upload and made some simple optimizations on top of it: drag upload, which requires attention to drag related events, and a progress bar, which can be implemented using Axios’ onUploadProgress.
Today we will further optimize this little file upload demo by adding the ability to verify file types.
Basic edition: suffix
As you can imagine, component libraries provide a beforeUpload method to verify the suffix of a file, so let’s verify the file type this way first.
First let’s look at the data type of file:
As you can see, there is a name field here, and we can verify this by intercepting the last.xxx:
const filename = fileRef.value.name;
const ext = filename.split(".").pop();
Copy the code
Up to this point, a simple suffix validation has been implemented, but there are some pitfalls in validating files based on suffixes: for example, the user deliberately changes the file’s suffix.
Here, the user changes the apk file suffix to PNG, and it can be seen that both file.type and name are regarded as pictures. If the user changes the file type to APK again after passing the verification of the front end, an unsafe file may be uploaded to the server.
Those interested can check out BurpSuite.
Upgraded version: binary
Before implementing the functionality, we can either perform winhex or simply install a hexdump in vscode to see how different files differ.
JPG
PNG
conclusion
The other types are similar, and interested readers can check for themselves. Here is the direct conclusion:
- JPG: the file header is FF D8 FF
- PNG: The file header is 89 50 4E 47
- GIF: the file header is 47 49 46 38
Reference: standard code for various types of file headers
Here we take GIF as an example to illustrate.
The first step is to encapsulate a method that converts the file header to a hexadecimal format. See the comments for details:
const blobToString = (blob: Blob): Promise<string> => {
return new Promise(resolve= > {
const reader = new FileReader();
reader.onload = () = > {
const result = (reader.result as string)
.split("")
// Convert to asC code
.map((v: string) = > v.charCodeAt(0))
// Convert to hexadecimal
.map((v: number) = > v.toString(16))
/ / filling 0
.map((v: string) = > v.padStart(2."0"))
.join("");
resolve(result);
};
reader.readAsBinaryString(blob);
});
};
Copy the code
So if we want to determine if a file is a GIF, just pass in the first four bytes:
const isGif = async (file: File): Promise<boolean> => {
const ret = await blobToString(file.slice(0.4));
return ret === "47 49 46 38";
};
Copy the code
Now let’s change the PNG file to GIF and test it again:
conclusion
The demo now has drag-and-drop uploading, a progress bar, and file type verification, which is starting to take shape. In future articles, we will show you how to implement functions such as large file slice uploading, file second uploading, and breakpoint uploading.
So let’s call it a day and look forward to the next meeting