如果“内容类型”:“多部分/表单数据”,CORS 问题

Posted

技术标签:

【中文标题】如果“内容类型”:“多部分/表单数据”,CORS 问题【英文标题】:CORS problem if "Content-type": "multipart/form-data" 【发布时间】:2019-03-29 00:10:21 【问题描述】:

我有两个域(客户端为 example.com,rest API 为 api.example.com),考虑到 CORS 策略,我从客户端向 API 请求。 预检请求按预期工作,除文件上传外,其他所有请求 (GET/POST/PUT/DELTE) 都能正常工作,这意味着 Content-type 是否为“multipart/form-data”。

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

从源“https://www.example.com”访问“https://api.example.com/video/upload”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。

这里是我的客户端(vuejs)来源:

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

谁能告诉我这段代码和配置有什么问题?! 感谢任何帮助!

【问题讨论】:

【参考方案1】:

通过在应用程序端应用 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);         

【讨论】:

【参考方案2】:

我有同样的问题,请求 (GET/POST/PUT/DELTE) 都可以工作,只有 Content-type:"multipart/form-data" 的文件上传遇到了 CORS 问题。 我多次尝试使用标题“Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers”。还是不行

最后,我发现 nginx 限制了文件上传大小。 所以,我在 nginx conf 文件中添加了“client_max_body_size 10M”。

cors 问题解决了。

【讨论】:

似乎上传的拒绝响应不包含所需的 CORS 标头,因此出现了 CORS 错误消息 - 这是误导性的。谢谢,这为我解决了问题。 谢谢,它现在为我解决了这个问题。我们可以在客户端请求上指定 Content-Length 标头,而不是更改 Nginx 上的 client_max_body_size。 谢谢,它也适用于我。我正在发送 post request multipart/form-data 并且浏览器报告 CORS 错误。设置client_max_body_size 后得到修复。 你拯救了我的一天 我遇到了同样的问题,花了一天时间寻找解决方案(因为误导性的 CORS 错误)。就我而言,这是 Multer 库和对临时文件夹的访问权限的问题(chmod 完成工作)。

以上是关于如果“内容类型”:“多部分/表单数据”,CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

CORS XMLHttpRequest 使用 POST 将多部分表单数据发送到 Softlayer 对象存储失败

Quarkus 找不到内容类型多部分/表单数据休息客户端的编写器

关于多部分/表单数据?

PrimeFaces 4.0/JSF 2.2.x 中的文件上传不适用于 AJAX - javax.servlet.ServletException:请求内容类型不是多部分/表单数据

如何使用 fetch 发布多部分表单数据?

使用 Redux、Thunk、Axios 创建多部分表单组件