closertb / closertb.github.io

浏览issue 或 我的网站,即可查看我的所有博客
https://closertb.site
32 stars 0 forks source link

fetch实(cai)践(keng)补充篇,文件上传Content-type multipart/form-data怎么设置 #8

Open closertb opened 5 years ago

closertb commented 5 years ago

写于:2017-07-16

原谅我是一个标题党,其实这个坑和fetch关系不大,归根结底是发送http响应的问题,闲话少说,直接说事。前面自己为了好玩,在自己的练手项目里,将vue-resource替换成原生JS的fetch API,使用效果还是极佳的,完全没有其他原生API那种晦涩感。

夯实基础

前面一篇文章fetch已入过门,所以这只说重点,之前使用vue-resource和fetch时,在Conten-type设置上吃过不少亏,所以自己做了大量功课,重要的事情说三遍,post请求content-type,即数据请求的格式主要设置方式:

好了,知道问题是啥了,删除请求头相关设置(Content-type),再发送,天啦,真的是耶,怎么会这样,不是说每个http请求都应该正确的设置自己的请求数据类型吗?我以前的书是不是白看了,啊,冷静,别人说的正确,那再通过dev-tools查看一下请求信息吧。

    Accept:*/*
    Accept-Encoding:gzip, deflate, br
    Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
    Connection:keep-alive
    Content-Length:88623
    content-type:multipart/form-data; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd
    Host:localhost:8089
    Origin:http://localhost
    Referer:http://localhost/
    User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
    Request Payload
    ------WebKitFormBoundaryAnydWsQ1ajKuGoCd
    Content-Disposition: form-data; name="file"; filename="Screenshot_2017-05-23-11-41-22-090_com.wacai365.png"
    Content-Type: image/png

    ------WebKitFormBoundaryAnydWsQ1ajKuGoCd
    Content-Disposition: form-data; name="name"

    denzel
    ------WebKitFormBoundaryAnydWsQ1ajKuGoCd
    Content-Disposition: form-data; name="flag"

    test
    ------WebKitFormBoundaryAnydWsQ1ajKuGoCd--

与上面失败的请求一比较,发现content-type后面居然多跟了boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd这样一串火星字符,再看发送的数据,数据之间都被请求数据类型的那个boundary字符串分割开,好像,我是有点懂,什么叫边界了,就是发http请求规定的数据交换规则.类似于:A发送请求给B,并告诉B,我给你送来了三个快递(但为了好搬运,我将它捆成了一个包裹),包裹拆分的规则在快递单上有说明,于是B就按A说的规则,进行包裹拆分。

问题讨论:post请求Content-type到底该不该设置

我得出的结论是,要正确设置。fetch 发送post字符类请求时,

  1. 非文件上传时,无关你发送的数据格式是application/x-www-form-urlencoded或者application/json格式数据,你不设置请求头,fetch会给你默认加上一个Content-type = text/xml类型的请求头,有些第三方JAX可以自己识别发送的数据,并自己转换,但feth绝对不会,不行,你可以试一下;
  2. 文件上传请求时,因为不知道那个boundary的定义方式,所以就如建议的一样,我们不设置Content-type。

如果本文有描述不正确的,欢迎指正,一起讨论,毕竟自己知识有限