为啥我的“multipart/form-data”标头不能阻止发送预检 (OPTIONS) 请求?
Posted
技术标签:
【中文标题】为啥我的“multipart/form-data”标头不能阻止发送预检 (OPTIONS) 请求?【英文标题】:Why isn't my "multipart/form-data" header preventing preflight (OPTIONS) requests from being sent?为什么我的“multipart/form-data”标头不能阻止发送预检 (OPTIONS) 请求? 【发布时间】:2021-02-25 15:15:04 【问题描述】:我正在使用 Angular 9。我有这些请求来获取二进制图像数据...
headersMultiPartForm = new HttpHeaders().set('Content-Type', 'multipart/form-data');
...
getImage(id)
let api = `$this.endpoint/person-library-image?id=$id`;
return this.http
.get(api, headers: this.headersMultiPartForm, responseType: "blob")
.pipe(retry(this.retry), catchError(this.handleError));
...
results.forEach(( componentarray, key ) =>
...
this.myService.getImage(id).subscribe(data =>
...
this.createImageFromBlob(data, index);
...
, () =>
...
);
);
我注意到请求需要一段时间才能完成,这似乎是因为它们被阻止等待 OPTIONS 请求完成。我想阻止发送这些预检 OPTIONS 请求。我认为我的“multipart/form-data”会阻止预检请求,但显然不是......
当我通过右键单击并复制为 CURL 检查实际请求时,我看到...
curl 'http://localhost:7071/api/person-library-image?id=127' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:81.0) Gecko/20100101 Firefox/81.0' -H 'Accept: application/json, text/plain, */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: http://localhost:4200/picture-library' -H 'Content-Type: multipart/form-data' -H 'Authorization: JWT <token>' -H 'Origin: http://localhost:4200' -H 'Connection: keep-alive' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache'
我有一个拦截器添加了 Authorization 标头,但我不知道其他标头来自哪里。有什么想法可以关闭它们以防止这些预检 OPTIONS 请求吗?
【问题讨论】:
这能回答你的问题吗? Why is an OPTIONS request sent and can I disable it? 我尝试按照建议添加额外的“Access-Control-Max-Age: 600”标头,但继续发送 OPTIONS 请求。Content-Type: multipart/form-data
应该是simple request,不需要预检;您的请求是否还有其他内容(例如由拦截器添加)将其排除在该类别之外?
【参考方案1】:
你说的是Simple vs Non-simple CORS requests。
确实,带有application/x-www-form-urlencoded
Content-Type 的 POST 很简单,如帖子中所述,因此不需要预检。但是,有一个重要的注意事项就是您的情况:
☝ Another tricky important condition - to be simple requests must have no manually
set headers. Default headers sent by browser are OK, we are talking only about
headers set by you from your request maker like XHR/fetch/axios/superagent/jQuery Ajax.
BTW request maker can set it without your agreement, so better start with pure
browser-native XHR of fetch API, don't use superagent/axios unless you know why
you need it. If you need to set a header by yourself still and still want keep
request simple you are allowed to white-listed request headers and their values, they
called CORS-safelisted. You can find their list and allowed values on fetch spec:
https://fetch.spec.whatwg.org/#cors-safelisted-request-header
检查请求中的标头,可能您有一些添加它的拦截器,根据https://fetch.spec.whatwg.org/#cors-safelisted-request-header
,它们很可能不是CORS-safelisted【讨论】:
以上是关于为啥我的“multipart/form-data”标头不能阻止发送预检 (OPTIONS) 请求?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 multipart/form-data 时不能正确发送带有 Unicode 的 POST 名称?