Method - Post请求 - 请求/接收参数方式

1.背景介绍

因为web开发,经常要写接口,前后端需要接口联调,所以必须前后端要清楚请求的方式,而且还必须结合具体的场景选择合适的请求方式,已经传递参数的方式,比如post请求,参数传递的方式也有些许不同,总结如下↓

 

后端语言:PHP 5.x  与 NodeJs 12.16.2

2.常用到参数传递内容类型 [即$_SERVER[CONTENT_TYPE]的值不同]

Note:

Method - Get请求 - 传递参数参见: https://blog.csdn.net/william_n/article/details/96486428

HTTP - GET 通过 Body 来发送数据 - 学习/实践:  https://blog.csdn.net/william_n/article/details/107941285

 

json/application   //$_SERVER[CONTENT_TYPE] 为 "application/json" ,有时为"application/json; charset=UTF-8"应该打印确认方可,尽量使用stripos函数进行判断

form-data  //$_SERVER[CONTENT_TYPE]为"multipart/form-data"

x-www-form-urlencoded  //$_SERVER[CONTENT_TYPE] 为 "application/x-www-form-urlencoded"

 

备注:

get请求方式,是接收不到$_SERVER[CONTENT_TYPE]的,

同时post仅仅以查询字符串的方式 [即可以认为也是get方式】传递参数也是没有接收不到$_SERVER[CONTENT_TYPE]的]

postman post请求,如果选择none,默认即 "application/x-www-form-urlencoded" [也是ajax的默认请求内容类型]

3.接口测试工具

Postman // 下载/安装/使用 见https://blog.csdn.net/william_n/article/details/91045285

4.json/application

简单介绍:

并不是只有后端可以返回给前端json数据,同时,前端也是可以向后端传递json格式的数据

[前后端都是进行json格式的自由传递和传唤,json本质上就是一串字符串,在网络中可以被转换为二进制传输 即字节[bite]流]

 

在postman中使用如下:

 

后端接收:

$data = file_get_contents('php://input'); //接受参数的结果是数组

$source = $data['__source__'];//获取参数  [本地开发环境测试,一直接收不到,原因在确定]

 

原因:

php 7.2.10不支持,改成5.x即可

 

postman中接收如下:

 

后端接收方式有二: [推荐使用第二种方式]

<?php
$data = json_decode($GLOBALS['HTTP_RAW_POST_DATA'] ,true);
var_dump($data);

 

$data1 = json_decode(file_get_contents("php://input") ,true);
var_dump($data1);

 

额外补充

1.PHP接收JSON格式的数据
在API服务中,目前流行采用json形式来交互。

给前端调用的接口输出Json数据,这个比较简单,只需要组织好数据,用json_encode($array) 转化一下,前端就得到json格式的数据。

接收前端提交的json数据稍微复杂一点,原因是:PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型。

 

因此,对 型如text/xml 或者 soap 或者 application/octet-stream 和 application/json 格式之类的内容无法解析,如果用$_POST数组来接收就会失败!

此时可以使用$GLOBALS['HTTP_RAW_POST_DATA']  或  file_get_contents('php://input') 来获取提交的数据

 
查看手册,可以发现$GLOBALS['HTTP_RAW_POST_DATA']  和  $_POST的区别:
  $_POST:通过 HTTP POST 方法传递的变量组成的数组,是自动全局变量。
  $GLOBALS['HTTP_RAW_POST_DATA'] :总是产生 $HTTP_RAW_POST_DATA 变量包含有原始的 POST 数据。

此变量仅在碰到未识别 MIME 类型的数据时产生。$HTTP_RAW_POST_DATA 对于enctype="multipart/form-data" 表单数据不可用。

 

也就是说

 

基本上$GLOBALS['HTTP_RAW_POST_DATA'] 和 $_POST是一样的。但是如果post过来的数据不是PHP能够识别的,你可以用 $GLOBALS['HTTP_RAW_POST_DATA']来接收,比如 text/xml 或者 soap 等等。

 

补充说明:PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型。

 

2.php://input

php://input 是个可以访问请求的原始数据的只读流 POST 请求的情况下,最好使用 php://input 来代替 $HTTP_RAW_POST_DATA,因为它不依赖于特定的 php.ini 指令。 而且,这样的情况下 $HTTP_RAW_POST_DATA 默认没有填充, 比激活 always_populate_raw_post_data 潜在需要更少的内存。 enctype="multipart/form-data" 的时候 php://input 是无效的。

 

Note:

在 PHP 5.6 之前 php://input 打开的数据流只能读取一次; 数据流不支持 seek 操作。 不过,依赖于 SAPI 的实现,请求体数据被保存的时候, 它可以打开另一个 php://input 数据流并重新读取。 通常情况下,这种情况只是针对 POST 请求,而不是其他请求方式,比如 PUT 或者 PROPFIND。[不甚理解??]

 

php://output
php://output 是一个只写的数据流, 允许你以 print 和 echo 一样的方式 写入到输出缓冲区。

5. form-data

简单介绍:

即form表单提交方式, 但是请求头的content-type=multipart/form-data.

如果用html来写即:

<form action="/signin" method="post" enctype="multipart/form-data">

    <p>Name: <input name="name" value="koa"></p>

    <p>Password: <input name="password" type="password"></p>

    <p><input type="submit" value="Submit"></p>

</form>

postman中即键值对,键的类型只能为text和file, 可以根据需要选择

 

 

PHP:

后端接受:$data = $_POST; var_dump($data); exit;

本质上$_POST全局变量接收,请结合具体的框架而定,即使用变体形式来接收参数.

 

如: PHP原生code

form表单中, 不论是否设置enctype="muiltpart/form-data"

即,是否设置请求头中Content-Type: multipart/form-data; 或者 Content-Type: application/x-www-form-urlencoded;

都是可以使用$_POST进行接收的.

 

Content-Type: multipart/form-data;

 

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

code:

index.php

post.php

 

如:YII2.0中

$request = Yii::$app->request;

$post = $request->post(); // 等价于: $post = $_POST;

 

如:laravel5.0中 [注意不是5.0以后的版本, 更高版本具体而定,也应该更容易]

 public function store(Request $request)//服务注入的方式
    {
        $name=$request->input('name');

         //可能需要$name=$request->get('name');//这里的get并不是代表get请求方式,而是获取的意思

         //或者 $name=$request->all(); 等价于: $post = $_POST;
    }

 

如:thinkphp5.0

$request = Request::instance(); //或者助手函数 $request = request();

$request->param('name');// 获取当前请求的name变量

 

未使用框架,则直接使用$_POST接收即可,但要做安全处理.

postman中如下:

 

 

[post form-data 参数传递数组]

 

NodeJs:

使用koa-bodyparser中间件中的

ctx.request.body 是接收不到数据的

原因:TBD  

解决:TBD  暂时先改成 application/x-www-form-urlencoded 即form表单中去掉 enctype="multipart/form-data" 即可。

详见下方

6.x-www-form-urlencoded [即ajax默认的请求方式, 也是form表单的默认content-type]

就是键值对,值可以为整形,字符串,布尔型,还可以是json

postman中如下:

后端接收如下:

$data = $_POST;
var_dump($data);
$source = json_decode($data['data'],true);
var_dump($source);
exit;

7.问题

1.nodeJs提供后端api,  form表单填写username+password登录,

浏览器中正常请求响应.

postman中使用form-data类型, 后端api不能接受到参数

改成x-www-form-urlencoded 类型, 正常请求响应.

 

截图:

浏览器

填写表单请求, 正常响应

Postman:

后端NodeJs code

 

原因: form表单中如果不设置enctype默认即x-www-form-urlencoded

登录页面的表单, 请求类型为[在浏览器中]x-www-form-urlencoded, 所以Postman中Content-Type也要为该类型方可.

 

问题:

谁来设置的表单请求的Content-Type?

程序员来设置form表单中的enctype属性. 见 5. form-data

 

 

补充:

Laravel 7.x中获取请求参数的方式, 如下:

 

...

8.参考

yii官网文档 :https://www.yiichina.com/doc/guide/2.0/runtime-requests

laravel学院文档  :  https://laravelacademy.org/post/68.html

thinkPHP官方文档 : https://www.kancloud.cn/manual/thinkphp5/118044

PHP接收JSON格式的数据 : https://www.cnblogs.com/cqingt/p/5853566.html 

PHP接收JSON数据官方文档:https://php.net/manual/zh/wrappers.php.php

contentType : 'application/json' not working for JSON String? [PHP] :https://stackoverflow.com/questions/25739625/contenttype-application-json-not-working-for-json-string-php

https://segmentfault.com/a/1190000013056786 // Http请求中的Content-Type

后续补充

...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值