javascript - OPTIONS 404 on Vue.js file upload
问题描述
I have defined cors in my express
app and don't have this issue with most of the routes. But, for a particular component that I use to upload images:
<input type="file" class="form-control" @change="imageChagned">
<div @click="postPhoto">Upload Photo</div>
methods:
postPhoto: function() {
console.log('sending photo');
axios.post( this.BASE_URL + "/profile/addphoto", {
file: this.image
}, this.jwt).then( (res) => {
console.log('after photo sent');
this.image = '';
console.log(res);
})
.catch( (error) => {
console.log(error);
});
},
imageChagned(e) {
var reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = (e) => {
this.image = e.target.result;
}
}
I get this error in browser:
OPTIONS http://127.0.0.1:3000/profile/addphoto 404 (Not Found)
dispatchXhrRequest @ xhr.js?b50d:178
xhrAdapter @ xhr.js?b50d:12
dispatchRequest @ dispatchRequest.js?5270:59
Promise.then (async)
request @ Axios.js?0a06:51
Axios.(anonymous function) @ Axios.js?0a06:71
wrap @ bind.js?1d2b:9
postPhoto @ AddPhoto.vue?0625:242
invoker @ vue.runtime.esm.js?2b0e:2023
fn._withTask.fn._withTask @ vue.runtime.esm.js?2b0e:1822
addphoto:1 Access to XMLHttpRequest at 'http://127.0.0.1:3000/profile/addphoto' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
here is the router that receives the post:
router.post('/addphoto', checkAuth, (req, res)=> {
console.log('add photo post received');
let filename = Math.floor(Math.random() * 100000);
let dir = './uploads/' + req.user.id;
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
base64String = req.body.file;
let str = base64String.split(';base64,');
let base64Image = str[1];
let extRaw = str[0];
let ext = extRaw.split('/')[1].toLowerCase();
let extArray = ['jpg', 'jpeg', 'png', 'gif'];
const buffer = Buffer.from(base64String.substring(base64String.indexOf(',') + 1));
fileSizeMB = buffer.length / 1e+6
//Check file extension
if (!extArray.includes(ext)) {
res.status(403).json({msg: 'error: file extention not allowed'})
return
};
//Check file size
if(fileSizeMB > 5) {
res.status(403).json({msg: 'error: file is too large'})
return
}
let imgId = filename + '.' + ext;
let filePath = dir + "/" + imgId;
fs.writeFile( filePath, base64Image, {encoding: 'base64'}, function(err) {
});
const photoFields = {};
photoFields.photos = []
let p = {}
p.imgId = imgId ;
p.visible = 'all'
User.findOne({ _id: req.user.id }).then(user => {
if (!user.images.profileImg.length > 0 ) {
user.images.profileImg = p.imgId;
}
user.images.photos.push(p);
user.save().then(()=>{
console.log('new photo is saved');
res.json({ images: user.images });
}).catch(err =>
console.log(err)
);
});
});
This problem bugs me for hours so really appreciate your hints to fix it.
The odd thing is that the component was working fine but it ceased to work after some small changes that I've made to my code.
解决方案
As the error indicates, there is no endpoint called /profile/addphoto
for method OPTIONS
. The route you posted would not be hit by an OPTIONS
request, since you specified that it only receives POST
.
The OPTIONS
request is used to let the requester know how it is allowed to use your API, so simply return status 200 after setting the cors headers. I usually do it by adding this to intercept any OPTIONS
request made to the API. Just add it somewhere in the beginning of the routing:
app.use(function(req, res, next) {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Headers', 'Origin, Accept, Content-Type, X-Requested-With, auth_token, X-CSRF-Token, Authorization');
res.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT, PATCH');
res.set('Access-Control-Allow-Credentials', 'true');
// intercept OPTIONS method
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
next();
});
推荐阅读
- python - Python获取特定的窗口标题
- json - JSON 到 PowerShell 需要帮助
- arrays - 在 Fortran 中放置数组分配的推荐做法
- createjs - 如何防止单击形状后面的形状在createjs中触发
- rust - 如何使用 Tokio 从 TcpStream 读取单个数据包?
- ios - UIView drawRect 子矩形
- ios - WKWebview 隐藏工具栏
- symfony - 订户呼叫两次 symfony
- javascript - 如何在 React.js 的处理函数中调用 Promise.all
- javascript - 对多个文档执行查询时,Firestore 安全规则 get() 不起作用