CORS problem if "Content-type": "multipart/form-data"
Asked Answered
C

4

15

I have two domains (example.com for client, api.example.com for rest API) where I request from client to API considering CORS policy. Preflight request works as expected and every other requests (GET/POST/PUT/DELTE) work well except file upload, means if Content-type is "multipart/form-data".

And I get following error in Chrome console:

Access to XMLHttpRequest at 'https://api.example.com/video/upload' from origin 'https://www.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here my client (vuejs) source:

var config = {
    headers: { "Content-Type": "multipart/form-data" },
    onUploadProgress(e) {
      if (e.lengthComputable) {
        self.percentage = Math.round(e.loaded / e.total * 100) + "%";
      }
    }
  };

  axios
    .post(apiUrl + `/video/upload`, formData, config)
    .then(response => {
      this.successes.push(
        response.data.videoName + " uploaded."
      );
    })
    .catch(e => {
      this.errors.push(message);
    });
},

And nginx configuration for CORS:

server {
listen 443 ssl default_server http2;
listen [::]:443 ssl default_server ipv6only=on;
root /var/www/example/public;
index       index.php index.html index.htm;
server_name api.example.com:443;

add_header Access-Control-Allow-Origin "*" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Access-Control-Allow-Methods "GET, POST, PUT, OPTIONS,  DELETE";
add_header Access-Control-Allow-Headers "Content-Type, X-Auth-Token, Origin, Authorization";

Could anyone please let me know what is wrong with this code & configuration?! Appreciate any help!

Carmacarmack answered 24/10, 2018 at 14:19 Comment(0)
C
8

Solved it by applying CORS in application side.

In detail, when browser sends preflight request error comes out. So, for the preflight requests I manually added Headers in application side. I have been using Laravel for backend, so created Cors middleware as floowing:

public function handle($request, Closure $next) {
    if ($request->getMethod() == "OPTIONS") {   
        $headers = [    
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',    
            'Access-Control-Allow-Headers' => 'Content-Type, Origin, Authorization' 
        ];
        return \Response::make('OK', 200, $headers);    
    }   

    return $next($request);         
}
Carmacarmack answered 5/11, 2018 at 8:10 Comment(0)
A
14

I have the same problem ,Requests (GET/POST/PUT/DELTE) all work, only fileupload with Content-type:"multipart/form-data" got the CORS problem. I tried many times with headers "Access-Control-Allow-Origin ,Access-Control-Allow-Methods, Access-Control-Allow-Headers". Still not work

Finally, I found the nginx limited the File Upload Size. So, I add "client_max_body_size 10M" in nginx conf file.

The cors problem solved.

Allstar answered 12/6, 2020 at 6:40 Comment(11)
It seems that the rejection response of the upload doesn't contain the needed CORS headers so the CORS error message appears - which is misleading. Thanks, this fixed the problem for me.Sargeant
thanks, it fixed the problem for me now. instead of change client_max_body_size on Nginx, we can specific Content-Length header on client request.Disinclination
Thanks, It works for me as well. I was sending post request multipart/form-data and browser was reporting CORS error. After setting client_max_body_size it get fixed.Comrade
You saved my dayTyburn
I have the same problem and spent a day finding a solution (because of misleading CORS error). In my case it was an issue with Multer library and access right to the temporary folder (chmod make the job done).Carousel
@AleksandrSkobeltcyn You are a lifesaverOgee
@Ogee chmod to which folder?Weidman
@AleksandrSkobeltcyn chmod to which folder?Weidman
@DanilT: upload folder where you are uploading files in api.Ogee
@Ogee in my case I use multer-sharp-s3, which uses stream, as I understand no temp folder is created during this process :( don't even know what to do. Turned off pm2 watch mode, added different nginx configs - still 502 :(Weidman
@DanilT: Currently, I am using busboy library to upload stream directly to s3 without saving it temporarily and I haven't seen any issue.Ogee
C
8

Solved it by applying CORS in application side.

In detail, when browser sends preflight request error comes out. So, for the preflight requests I manually added Headers in application side. I have been using Laravel for backend, so created Cors middleware as floowing:

public function handle($request, Closure $next) {
    if ($request->getMethod() == "OPTIONS") {   
        $headers = [    
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',    
            'Access-Control-Allow-Headers' => 'Content-Type, Origin, Authorization' 
        ];
        return \Response::make('OK', 200, $headers);    
    }   

    return $next($request);         
}
Carmacarmack answered 5/11, 2018 at 8:10 Comment(0)
R
0

I solve this by adding boundary in content-type headers: headers: {'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,},

Rotary answered 25/4, 2024 at 0:55 Comment(0)
B
-1

Maybe this helps someone in the future. I had the same problem (browser reporting CORS issue), but actually CSRF was the problem.

Balky answered 6/1, 2024 at 16:32 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.