Frontend is in react, server is in node.js express. Trying to upload a file to the server (set up on amazon - everything works fine locally) using XMLHttpRequest I get an error:
Access to XMLHttpRequest at 'https://xxx/api/video' from origin 'https://xxx/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I upload the file in chunks (10mb each) and there is no problem when the file is smaller (<40mb), but the problem occurs when the file is larger. This is incomprehensible as each chunk is always 10mb but somehow the server rejects those chunks which are part of a larger file. Following this lead, I removed the content-range header, which contained information about the total file size, but it didn't help.
For the cors service, I use:
app.use(cors({
origin: true,
credentials: true
}));
Code to upload the file:
const saveFile = () => {
if(videoName.length < 1){
setVidNameErr(true);
}
if((uploadedFile || videoData) && (videoName.length > 0)){
setUploadProgress(0);
//options
const chunkSize = 10000000; // size of one chunk: 10 MB
let videoId = '';
let chunkCounter = 0;
const file = recordingMode ? videoData[0] : uploadedFile;
const fileSize = recordingMode ? videoData[0].size : uploadedFile.size;
const createChunk = (videoId: string, start: number) => {
chunkCounter ++;
const chunkEnd = Math.min(start + chunkSize , fileSize);
const chunk = file.slice(start, chunkEnd);
const formData = new FormData();
if(videoId?.length > 0){
formData.append('videoId', videoId);
}
formData.append('title', videoName);
formData.append('file', chunk);
uploadChunk(formData, start, chunkEnd);
}
const updateProgress = (e: any) => {
if (e.lengthComputable) {
const numberOfChunks = Math.ceil(fileSize/chunkSize);
const percentComplete = Math.round(e.loaded / e.total * 100);
setUploadProgress(
Math.round(
(chunkCounter - 1) / numberOfChunks * 100 + percentComplete / numberOfChunks
)
)
}
}
const uploadChunk = (formData: any, start: number, chunkEnd: number) => {
setIsVideoBeingSent(true);
const req = new XMLHttpRequest();
const contentRange = "bytes " + start + "-" + (chunkEnd - 1) + "/" + fileSize;
req.upload.addEventListener("progress", updateProgress);
req.open("POST", `${process.env.URL}/api/video`, true);
req.withCredentials = true;
req.setRequestHeader('lang', router.locale as string)
req.setRequestHeader("Content-Range", contentRange);
//req.setRequestHeader("Content-Type", 'multipart/form-data; boundary=--');
req.onload = () => {
const resp = JSON.parse(req.response)
resp.statusCode === 401 && logoutUser()
setRequestErr({
mess: resp.message,
code: resp.statusCode
})
videoId = resp.videoId;
start += chunkSize;
if(start < fileSize){
createChunk(videoId, start);
} else{
chunkCounter = 0;
setIsVideoBeingSent(false);
setModalType('info')
if(resp.status === 200){
setModalInfoType('success')
} else{
setModalInfoType('fail')
}
}
}
req.send(formData);
}
createChunk(videoId, 0);
}
};
Based on: https://api.video/blog/tutorials/uploading-large-files-with-javascript
Uploading a file via form using this code: https://www.geeksforgeeks.org/file-uploading-in-node-js/
works, however when changing the file upload using XMLHttpRequest the error from cors reappears.
What could be causing this problem and how to fix it?