如果"Content-type": "multipart/form-data",则存在CORS问题。

14

我有两个域名(example.com 用于客户端,api.example.com 用于 REST API),在客户端到 API 请求时需要考虑 CORS 策略。预检请求按预期工作,并且除了文件上传以外的每个其他请求(GET/POST/PUT/DELETE)都可以正常工作,意味着如果 Content-type 是“multipart/form-data”,则无法正常工作。

我在 Chrome 控制台中收到以下错误:

访问 'https://api.example.com/video/upload' 源于 'https://www.example.com' 的 XMLHttpRequest 已被 CORS 策略阻止:所请求的资源未包含 'Access-Control-Allow-Origin' 头信息。

这是我的客户端(Vue.js)源代码:

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

关于CORS的nginx配置:

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

请问这段代码和配置有什么问题吗?!感谢任何帮助!

2个回答

14

我遇到了同样的问题,所有请求(GET/POST/PUT/DELETE)都没问题,只有文件上传(Content-type:"multipart/form-data")出现了CORS问题。

我试过很多次加上头信息 "Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers" ,但还是不行。

最后,我发现是nginx限制了文件上传大小。所以我在nginx配置文件中添加了 "client_max_body_size 10M"。

这样,CORS问题就解决了。


2
谢谢,这对我也有效。我正在发送multipart/form-data的POST请求,浏览器报告CORS错误。设置了client_max_body_size后问题得到解决。 - Pranav Kumar
你救了我的一天。 - Jinho Jang
2
我也遇到了同样的问题,花了一天时间找到了解决方案(因为CORS错误有误导性)。在我的情况下,这是Multer库和访问临时文件夹权限的问题(chmod解决了问题)。 - Aleksandr Skobeltcyn
@AleksandrSkobeltcyn 要对哪个文件夹进行 chmod 操作? - Daniel
在我的情况下,我使用multer-sharp-s3,它使用流,据我所知,在此过程中不会创建临时文件夹:(甚至不知道该怎么办。关闭了pm2的观察模式,添加了不同的nginx配置-仍然是502 :( @cissharp - Daniel
显示剩余6条评论

6

我通过在应用程序端应用CORS解决了这个问题。

具体来说,当浏览器发送预检请求时会出现错误。因此,对于预检请求,我在应用程序端手动添加了头信息。 我一直在使用Laravel作为后端,所以创建了如下的Cors中间件:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接