fetch请求php的坑,fetch请求问题

首先, 数据要在网络上传输, 就会涉及到数据序列化的问题, 因为双边数据在内存中的形式极有可能不一样, 这个时候需要约定一种双边都认可并且能实现的序列化方式, 使得数据能够被发送方序列化, 并且在网络中传输, 最终被接收方正确的反序列化.

为了适应不同的数据以及客户端环境, HTTP协议约定通过请求头中的Content-Type字段来确定数据序列化协议, 常用的有:application/x-www-form-urlencoded

multipart/formdata

application/json

其中第一个和第二个是几乎所有浏览器和服务器都支持的协议, 第一个用来传输文本信息, 而二个用来传输文本信息或者二进制数据, 比如文件上传等. 在没有二进制数据时, 通常使用第一种方式, 因为其压缩比例相对较高. 而第三个就是我们熟悉的JSON序列化.

无论是第一种还是第二种协议, 其所能处理的数据都是只有一层的简单key-value形式. 并且第一种的值只能是字符串, 第二种除了是字符串之外还可以是二进制数据. 为了表达多层的数据结构, 这两种协议都使用root[first][second]的形式作为key, 接收方在收到这样的key之后应该将其解析成三层结构(似乎并不是协议约定的事情). 比如在PHP中, 应该解析成三层的关联数组:

$data = array(

'root' => array(

'first' => array(

'second' => 'value'

)

)

)

而对于root[][]或者root[0][0]等格式, 应当解释成JS中的数组, 也就是PHP中的非关联数组:$data = array(array(array('value')))

fetch是一个whatwg推出的基于Promise的对XMLHttpRequest的封装接口标准(这个标准还没有被W3C采纳, 所以浏览器中的实现都不是最终的版本, 浏览器也没有被要求去实现这个接口). 这个标准提供了一个全局的函数fetch, 其签名如下:

partial interface WindowOrWorkerGlobalScope {

[NewObject] Promise fetch(RequestInfo input, optional RequestInit init);

};

其中RequestInit中包含了请求所需的参数, 其结构如下:

dictionary RequestInit {

ByteString method;

HeadersInit headers;

BodyInit? body;

USVString referrer;

ReferrerPolicy referrerPolicy;

RequestMode mode;

RequestCredentials credentials;

RequestCache cache;

RequestRedirect redirect;

DOMString integrity;

boolean keepalive;

any window; // can only be set to null

};

其中的body字段即是放到请求body中的数据, 其结构BodyInit定义如下:typedef (Blob or BufferSource or FormData or URLSearchParams or ReadableStream orUSVString) BodyInit

对于不同的body类型, fetch会自动设置请求头中的Content-Type, 具体请参考: https://fetch.spec.whatwg.org....如果传入的body是一个JS中的普通Object, 会被忽略, 如果是一个string, 则会设置头为text/plain, 这个时候服务端根据Content-Type只能将请求的body解析为字符串, 这个时候在$_POST为空数组, 所以都会为空.

当传入一个已经序列化的字符串时, 可以通过在请求参数的headers中手动设置Content-Type来指定序列化协议. 比如以JSON为序列化格式:

fetch('/', {

headers: {

'Content-Type': 'application/json',

},

method: 'POST',

body: JSON.stringify({first: {second: '1'}})

})

对于你的疑问, 也就是如何把JS中的Object按照application/x-www-form-urlencoded的格式进行序列化, 现在npm中有很多包可以做这样的事情, 比如qs等:

import {stringify} from 'qs'

fetch('/', {

method: 'POST',

headers: {

'Content-Type': 'application/x-www-form-urlencoded'

},

body: stringify({root: {first: {second: 1}}})

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值