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?
You need to allow your domain on your app. So add given code in your app.js.
app.use(function(req,res,next) {
req.connection.setNoDelay(true)
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Origin", "https://xxx");
res.header('Access-Control-Expose-Headers', 'agreementrequired');
next()
})
you need to change only the domain name. https://xxx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With