Nahrávání souborů je v dnešní době jednou z nejběžnějších funkcí webové aplikace. Existuje mnoho knihoven JavaScriptu, které zvládnou nahrávání souborů jako vánek.
Ale nenačteme celou knihovnu jen pro tuto jedinou funkci, kterou lze snadno zvládnout v nativním JavaScriptu pomocí Fetch API. Fetch je slibná moderní náhrada XHR pro vytváření požadavků HTTP v prohlížeči.
Načíst nahrání souboru
Pojďme na váš web přidat následující vstupní prvek HTML:
<input type="file" id="avatar">
Nyní přidejte posluchač událostí na vstup, který se spustí, když uživatel vybere soubor:
// select file input
const input = document.getElementById('avatar');
// add event listener
input.addEventListener('change', () => {
uploadFile(input.files[0]);
});
Dále přidejte uploadFile()
metoda, která obdrží File
objekt jako vstup a nahraje jej na server s fetch()
pomocí rozhraní FormData:
const uploadFile = (file) => {
// add file to FormData object
const fd = new FormData();
fd.append('avatar', file);
// send `POST` request
fetch('/upload-avatar', {
method: 'POST',
body: fd
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));
}
Ověřte typ a velikost souboru
Před zahájením nahrávání na server můžete také ověřit vlastnosti (jako je typ souboru a velikost souboru) souboru:
const uploadFile = (file) => {
// check file type
if(!['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'].includes(file.type)) {
console.log('Only images are allowed.');
return;
}
// check file size (< 2MB)
if(file.size > 2 * 1024 * 1024) {
console.log('File must be less than 2MB.');
return;
}
// ...
}
Ovládání nahrávání souborů na straně serveru pomocí Node.js
Zde je příklad kódu, který zpracovává výše uvedený požadavek na nahrání souboru v Node.js. Používám express-fileupload
— jednoduchý Express middleware pro nahrávání souborů. Analyzuje multipart/form-data requests
, rozbalí soubory, pokud jsou k dispozici, a zpřístupní je pod req.files
vlastnost:
app.post('/upload-avatar', async (req, res) => {
try {
if(!req.files) {
res.send({
status: false,
message: 'No file uploaded'
});
} else {
//Use the name of the input field (i.e. "avatar") to retrieve the uploaded file
let avatar = req.files.avatar;
//Use the mv() method to place the file in upload directory (i.e. "uploads")
avatar.mv('./uploads/' + avatar.name);
//send response
res.send({
status: true,
message: 'File is uploaded',
data: {
name: avatar.name,
mimetype: avatar.mimetype,
size: avatar.size
}
});
}
} catch (err) {
res.status(500).send(err);
}
});
Ovládání nahrávání souborů na straně serveru pomocí Spring Boot
Pokud plánujete použít Spring Boot pro back-end, zde je ukázkový úryvek kódu, který zpracuje výše uvedený požadavek na nahrání souboru ve Spring Boot:
@PostMapping("/upload-avatar")
@ResponseBody
public ResponseEntity<String> fileUpload(MultipartFile avatar) {
try {
// upload directory - change it to your own
String UPLOAD_DIR = "/opt/uploads";
// create a path from file name
Path path = Paths.get(UPLOAD_DIR, avatar.getOriginalFilename());
// save the file to `UPLOAD_DIR`
// make sure you have permission to write
Files.write(path, avatar.getBytes());
}
catch (Exception ex) {
ex.printStackTrace();
return new ResponseEntity<>("Invalid file format!!", HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>("File uploaded!!", HttpStatus.OK);
}