Skip to content

XMLHttpRequest的upload属性对CORS的影响 #19

Open
@jappp

Description

@jappp

前言

之前在做一个图片上传的需求时,涉及到了跨域 CORS 上简单请求和非简单请求上的一点坑,在此记录希望能给其他人排坑。


当时和后端同学沟通好了,服务端已经实现了跨域设置,可以直接发送 multipart/form-data 类型的请求建立简单请求,但是实际过程还是产生了 OPTIONS 预检请求,并且返回为403(Forbidden)。

image

但是后端告诉我,同样的接口在同样的域名下,其他业务方调用并没有产生 OPTIONS 预检请求,并且成功发出 POST 请求。

排查思路

排查步骤:

  1. 用 Chrome net internals 查看请求链路以及头部并无发现异常
  2. 借鉴成功业务方,直接发送了一个 axios 请求发现确实是正常的,没有产生预检请求,那问题就能定位到是我使用的上传组件导致的。
  3. 由于我使用了一个上传组件,内部对我来说是一个黑盒。一开始我把重点放在了是否有多余的请求头添加导致产生了 OPTIONS 请求。但是通过对组件 ajax 上传部分的源码翻阅,发现并没有添加多余的请求头,这一点也排除。

既然产生了预检请求,所以我重新仔细翻看了 CORS 简单请求和非简单请求的差异。发现 MDN 关于简单请求上有一个关键词描述 XMLHttpRequest.upload ,不能调用或实现该方法。

就是说当 xhr 对象实现了 upload 方法也就不能被当作一个简单请求,浏览器会把它当作非简单请求处理

image

此时再根据这条线索去查阅源码就一目了然了,组件内部果然重写实现了该方法

image

至此问题就解决了。

总结

排查问题的核心其实就是找到差异点,然后针对差异点去做进一步的深究,其实往往就事半功倍了。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions