node.js - 上传文件时: CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

标签 node.js reactjs express

前端采用 React,服务器采用 Node.js Express。尝试使用 XMLHttpRequest 将文件上传到服务器(在亚马逊上设置 - 本地一切正常)我收到错误:

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.

我分块上传文件(每个10mb),当文件较小(<40mb)时没有问题,但当文件较大时就会出现问题。这是不可理解的,因为每个 block 总是 10mb,但服务器以某种方式拒绝了属于较大文件的那些 block 。按照这个思路,我删除了内容范围 header ,其中包含有关总文件大小的信息,但这没有帮助。

对于cors服务,我使用:

app.use(cors({
    origin: true,
    credentials: true
}));

上传文件的代码:

 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);
        }
    };

基于: https://api.video/blog/tutorials/uploading-large-files-with-javascript

使用以下代码通过表单上传文件: https://www.geeksforgeeks.org/file-uploading-in-node-js/

可以工作,但是当使用 XMLHttpRequest 更改文件上传时,cors 的错误会再次出现。

什么可能导致此问题以及如何解决它?

最佳答案

您需要在您的应用上允许您的域。因此,在您的 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()
})

您只需更改域名。 https://xxx

关于node.js - 上传文件时: CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70665836/

相关文章:

node.js - Sequelize 中的 UUID 主键给出了 : (node:6927) UnhandledPromiseRejectionWarning: SequelizeDatabaseError: Field 'id' doesn't have a default value)

javascript - 如何根据套接字事件呈现新的 jade View ?

javascript - 使用角色和特定用户ID来限制在react/node/express/mysql中可以查看哪些部分?

node.js - cors 子域失败

javascript - 中间件不会捕获带有等待的 Promise 拒绝

reactjs - 找到路由器(用于中继现代) protected 身份验证路由

reactjs - typescript 错误 2304 : Cannot find name 'div' - CRA TypeScript Template

javascript - node.js setTimeout 的替代方案

python - 为什么越来越,gyp ERR!堆栈错误 : Can't find Python executable "python"?

node.js - 使用 react-devtools 破解身份验证