为何文中最后的 patch 方法要使用 x-www-form-urlencoded 而不是 form-data?
我们知道,HTTP请求中form-data 既可以上传键值对,也可以上传文件,x-www-form-urlencoded只能传键值对。
文中最后部分patch方法那里,去更新User信息时,只传键值对而无文件,理论上应该选择form-data和x-www-form-urlencoded都可以。实际测试只有x-www-form-urlencoded能成功更改用户信息。这是为什么呢?
高认可度评论:
『理论上应该选择 form-data 和 x-www-form-urlencoded 都可以』
http 协议 put 和 patch 只能使用 x-www-form-urlencoded
@liyu001989 老师,我把这个大致读了一下,
似乎此文是在说明ENCTYPE=x-www-form-urlencoded用来上传图片是不够的,因此引入了ENCTYPE=multipart/form-data
我再次看了源码:
在\Symfony\Component\HttpFoundation\Request::createFromGlobals方法中,可以看到
$request->getContent()
这个方法,而这个方法中有这么一段代码:参考这里,可知
php://input is not available with enctype="multipart/form-data".
。enctype="multipart/form-data"时,file_get_contents('php://input') 为类似这样的字符串:
而enctype="x-www-form-urlencoded"时,file_get_contents('php://input') 为这样的字符串。
因此,ENCTYPE需要为x-www-form-urlencoded,才能进行下一步的parse_str操作。
如果不考虑理论的话,或许光看源码也可以得出这个结论。
在\Symfony\Component\HttpFoundation\Request中,有一个createFromGlobals方法,作用是Creates a new request with values from PHP's super globals. 代码:
$attributes = $request->only(['name', 'email', 'introduction']);
的结果就是空,$user->update($attributes);
就是什么也没有update。『理论上应该选择 form-data 和 x-www-form-urlencoded 都可以』
http 协议 put 和 patch 只能使用 x-www-form-urlencoded
@liyu001989 之前的教程里,PUT、PATCH、DELETE 请求是通过在表单里伪造一个 _method 参数,Api 的这几个请求不是放在表单参数里的吗?
@liyu001989 老师,“http 协议 put 和 patch 只能使用 x-www-form-urlencoded”,我只找到了这个依据:
https://developer.mozilla.org/en-US/docs/W... , 里面写了"Allowed in HTML forms: No"
有没有更权威的依据?谢谢。
如果不考虑理论的话,或许光看源码也可以得出这个结论。
在\Symfony\Component\HttpFoundation\Request中,有一个createFromGlobals方法,作用是Creates a new request with values from PHP's super globals. 代码:
$attributes = $request->only(['name', 'email', 'introduction']);
的结果就是空,$user->update($attributes);
就是什么也没有update。@hustnzj 我表述的可能有误解,http 默认情况下就是使用
x-www-form-urlencoded
,需要上传二进制数据的时候需要使用 post 并使用 form-data 。你看一看看 https://tools.ietf.org/html/rfc1867#sectio...
@liyu001989 老师,我把这个大致读了一下,
似乎此文是在说明ENCTYPE=x-www-form-urlencoded用来上传图片是不够的,因此引入了ENCTYPE=multipart/form-data
我再次看了源码:
在\Symfony\Component\HttpFoundation\Request::createFromGlobals方法中,可以看到
$request->getContent()
这个方法,而这个方法中有这么一段代码:参考这里,可知
php://input is not available with enctype="multipart/form-data".
。enctype="multipart/form-data"时,file_get_contents('php://input') 为类似这样的字符串:
而enctype="x-www-form-urlencoded"时,file_get_contents('php://input') 为这样的字符串。
因此,ENCTYPE需要为x-www-form-urlencoded,才能进行下一步的parse_str操作。
@hustnzj 学习就怕你这种较真的人
php 中 $_POST这样写的:当 HTTP POST 请求的 Content-Type 是 application/x-www-form-urlencoded 或 multipart/form-data 时,会将变量以关联数组形式传入当前脚本。浏览器中,只能是 GET 或者 POST 请求方法,postman 则可以是 PUT 或者 PATCH。 当传统 http 发起 PATCH 请求(表单页面通过 _method 构造了一个假的提交方法,用来匹配路由方法,本质还是 POST 方法),laravel 是通过 $_POST 获取表单数据。postman 等非传统的方式用 PUT 后者 PATCH 提交表单,$_POST 获取不到表单数据,laravel 会判断请求方法,如果是 PUT 或者 PATCH,并且 content-type:x-www-form-urlencoded ,就会从 php://input 获取表单数据,至于 symfony 为什么这么实现,可能是为了遵守规范。
如果非要在 postman 中用 multipart/form-data,可以用 POST 方法模拟网页提交表单数据,并在表单数据中加入变量 _method=PATCH。
@_杭城浪子 我觉得他很厉害 会自己去寻找信息 会弄清真正的原理
@liyu001989
http 协议 put 和 patch 只能使用 x-www-form-urlencoded
这个是哪里来的? 查了下,http标准并没有限制patch
和put
请求的数据格式 stackoverflow.com/questions/173758...这问题是 laravel/synfony 框架设计的问题,github.com/laravel/framework/issue...,而issue里面框架的维护者声称这是php的问题
我在这里弱弱地说两个使用PATCH方法更新图片资源的方法,不喜勿喷。
(官方issue:https://github.com/laravel/framework/issues/13457)
第一种伪造PATCH方法,请求时正常用POST:
第二种方法:传递base_64编码后的字符串