Vue.js文件上载的选项404

时间:2018-12-07 12:04:32

标签: javascript node.js express vue.js axios

我已经在我的express应用中定义了cors,并且大多数路线都没有这个问题。但是,对于用于上传图片的特定组件:

<input type="file" class="form-control" @change="imageChagned">

<div  @click="postPhoto">Upload Photo</div>  

方法:

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

我在浏览器中收到此错误:

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.

这是收到帖子的路由器:

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

    });


  });

这个问题困扰着我几个小时,非常感谢您提出的修复建议。

奇怪的是,该组件运行良好,但是在我对代码进行一些小的更改后,该组件停止工作。

1 个答案:

答案 0 :(得分:1)

如错误所示,方法/profile/addphoto没有名为OPTIONS的端点。由于您指定仅接收OPTIONS,因此POST请求不会击中您发布的路由。

OPTIONS请求用于让请求者知道如何使用您的API,因此只需在设置cors标头后返回状态200。我通常通过添加它来拦截对API发出的 any OPTIONS请求。只需将其添加到路由的开头:

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