Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS Fails when uploading a file

Here I meet a little problem with my code.

What I do

I have a laravel application in backend (on port 8000) in which I created a CORS middleware that allows me to make cross origin requests from my front-end (on port 8080)

Here is my Middleware Cors

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', env("CORS_DOMAINS", 'http://localhost:8080'))
            ->header('Access-Control-Allow-Methods', 'OPTIONS,POST,GET ,PUT, PATCH, DELETE')
            ->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-type, Authorization', 'Accept-Language','Content-Disposition', 'Accept');
    }
}

Until now everything works well if I make simple requests with vue-resource. But when I pass as data a formData The CORS fails.

I created a Javascript class for uploading files

In the lines that follow it is only this line that interests us (it is the one who makes the XHR request):

 return this.vm.$http.post(this.options.url, this.data)

My Upload Class

class Upload {
  defaultOptions = {
    extensions: null,
    maxSize: null,
    multiple: false,
    inputName: 'file'
  }
  errors = []
  constructor (files, Vue, options) {
    this.files = files
    this.vm = Vue
    this.options = Object.assign(this.defaultOptions, options)
    this.data = new FormData()
    return this.upload()
  }

  upload () {
    if (!this.files.length) return
    for (let i = 0; i < this.files.length; i++) {
      if (this.checkFile(this.files[i])) {
        this.pushToData(this.files[i])
      } else {
        this.errors.forEach((error) => this.options.errorsCallback(error))
      }
    }
    for (let key in this.options.params) {
      if (this.options.params.hasOwnProperty(key)) { this.data.append(key, this.options.params[key]) }
    }
    return this.vm.$http.post(this.options.url, this.data)
  }
  checkFile (file) {
    return this.checkSize(file) && this.checkExtensions(file)
  }
  checkSize (file) {
    if (this.options.maxSize && file.size > this.options.maxSize) {
      this.errors.push('The file `' + file.name + '` size must not exceed' + this.options.maxSize)
      return false
    }
    return true
  }
  checkExtensions (file) {
    if (this.options.extensions && !this.options.extensions.includes(file.type.split('/')[1])) {
      this.errors.push('The file `' + file.name + '` must have one of theses extensions :' + this.options.extensions.join(','))
      return false
    }
    return true
  }
  pushToData (file) {
    this.data.append(this.options.inputName, file)
  }
}

export default Upload

What I want

I want the query to succeed when I send a formData

What I get

I get a message saying that the Access-Control-Allow-Origin header is missing but this header is allowed in my Cors. I do not understand this error. Une Image de L'erreur

like image 989
Aboubacar Ouattara Avatar asked May 02 '18 22:05

Aboubacar Ouattara


2 Answers

CORS isn't the real problem here, your middleware works fine. Look directly above, and you'll notice an earlier error says 500 (Internal Server Error)

When your server throws a 500 error, Chrome will occasionally think it's a CORS issue. Fix the 500 error and that CORS problem will go away.

like image 131
Wyatt Arent Avatar answered Oct 13 '22 22:10

Wyatt Arent


Late to the party here, but just wanted to share my response for anybody else who may be experiencing the same.

I have an Nginx API Gateway, and what I found out was that there was a max body size parameter in the server block on the gateway, and so this was causing the CORS error (whenever I uploaded a file that caused the request to go over that limit).

I am not sure what exactly about this caused the error to be shown as a CORS error, but this was the source for me ... hopefully it can help someone else too!

like image 22
Ridge Robinson Avatar answered Oct 13 '22 22:10

Ridge Robinson