前端采用 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/