Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While uploading files: CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

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?

like image 749
Cery Avatar asked Nov 28 '25 10:11

Cery


1 Answers

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

like image 184
Pushpendra Kumar Avatar answered Nov 29 '25 23:11

Pushpendra Kumar