客户端发送数据及服务器获取参数的几种形式

11613次阅读 814人点赞 作者: WuBin 发布时间: 2021-03-09 14:55:01
扫码到手机查看

查询字符串传递及用$_GET获取

在前端,将参数拼接在查询字符串上,如 www.wubin.work/xx.php?id=10&param=ok

在服务端,使用$_GET获取

$id = $_GET['id'];
$param = $_GET['param'];

HTTP请求头

enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码,默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。

enctype可选项如下:

描述
application/x-www-form-urlencoded在发送前编码所有字符(默认)
multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
application/json作为请求头告诉服务端消息主体是序列化的JSON字符串。除低版本的IE,基本都支持。
text/plain空格转换为 “+” 加号,但不对特殊字符编码。

HTTP 协议是以ASCII码传输。他是建立在 TCP/IP 协议之上的应用层规范, 规定HTTP 请求分为三个部分:

  • 状态行
  • headers请求头
  • entity-body 消息主体

HTTP协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以 POST 提交数据包含了 Content-Type 和消息主体编码方式两部分,下面就正式开始介绍它们。

三种常见的POST提交方式

以下例子均以JQuery为例。以下是基本的数据结构:

var data_obj = {
     one: 'first',
     two: 'second'
};
// 将对象转化为字符串
var data_str = JSON.stringify(data_obj);

application/x-www-form-urlencoded

HTTP中默认的提交数据的方式。提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。(JQ不传递contentType默认就是x-www-form-urlencoded)如:

$.ajax({
     url: 'post-json.php',
     type: 'POST',
     data: data_obj
     ...
});

在chrome的network-formData可以看到 会拼接成one=first&two=second。传入json对象的时候,这种方式会以键值对的形式将对象序列化,所以传进去的对象实际上还是变成了字符流。

这里特别注意一点:这里的data不可以传入data: data_str(字符串)! (以下对比3.3 application/json进行区分!)比如

$.ajax({
     url: 'post-json.php',
     type: 'POST',
     data: data_str
});

post-json.php:

var_dump($_POST);
exit();

最终的结果是: array(1) { ["{"one":"first","two":"second"}"]=> string(0) "" },传入的JSON字符串成为了键名!

如果要传入字符串,那么一定是要传入一个对象:如

$.ajax({
   url: 'post-json.php',
   type: 'POST',
   data: {str: data_str},
   ...
});

最终的结果是:array(1) { ["str"]=> string(30) "{"one":"first","two":"second"}" } 可以通过$_POST['str']获取。

multipart/form-data

一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须将 的enctype设为multipart/form-data

content-type: multipart/form-data; boundary=--wxx
// form表单的数据,以boundary的字符串进行分割各个请求参数,结果就是
--wxx Content-Disposition: form-data;name="one"
first
--wxx Content-Disposition: form-data;name="two"
second
/* 以上在chrome的控制台 network-xhr-formData中可看到 */

application/json

application/json作为请求头,用来告诉服务端消息主体是序列化的JSON字符串,除了低版本的IE,基本都支持。

注意这里发送的数据必须是JSON字符串!!!

$.ajax({
    url: 'post-json.php',
    type: 'POST',
    contentType: 'application/json',
    data: data_str, // 必须是字符串!
    // 当contentType: 'application/json'时候,传入的是对象data_obj,那么后台不会接收到数据
    success: function() {
         console.log('ok');
    }
});

在jquery的ajax中,如果没加contentType:"application/json",那么data就应该对应的是json对象;

如果加了contentType:"application/json",那么ajax发送的就必须是(json)字符串。

post-json.php(重点):

// php://input 是个可以访问请求的原始数据的只读流
// enctype="multipart/form-data" 的时候 php://input 是无效的。
$re = file_get_contents("php://input");
// 将获取的json字符串转化为数组
$reArr = json_decode($re, true);

print_r($reArr);

$one = $reArr['one'];
$two = $reArr['two'];

echo $one . ' ' . $two;

注意,服务端获取application/json请求头,必须要使用file_get_contents("php://input"); 使用$_POST无法获取application/json请求头的数据。

最终结果:(print_r的->)Array ( [one] => first [two] => second )   (echo的->)first second

在vue中使用axios提交数据

在工作中,有这么一个场景,提交一个图片的url,服务端进行验证然后存入数据库,成功返回一个json。
// 公共方法的代码
import axios from "axios";
import { POST_IMG_URL } from "api/config";

function postUrl(url, paramObj) {
  return axios.post(url, paramObj).then((res) => {
    return Promise.resolve(res.data);
  }).catch((err) => {
    return Promise.reject(err);
  });
}

服务端使用$_POST进行接收

header("Access-Control-Allow-Origin: *");
header("content:application/json;chartset=uft-8");
$zt_id = isset($_POST['id']) ? intval($_POST['id']) : false;
$url = isset($_POST['url']) ? $_POST['url'] : false;

当数据使用json对象提交

export function postImgUrl(ztId, url) {
  let obj = {
    id: ztId,
    url: url
  };
  return postUrl(POST_IMG_URL, obj);
}

这时得到的,请求头是application/json 请求发送失败。因为$_POST无法接收JSON对象。

使用拼接字符串

export function postImgUrl(ztId, url) {
  let str = `id=${ztId}&url=${url}`;
  return postUrl(POST_IMG_URL, str);
}

这次将获取到的参数使用&符号拼接,结果发现发送成功了。

上图是点击view source 是将参数使用&符号链接了。

由此可见,axios是根据第二个参数提交的格式,来自动设置content-type的。如果要使用json格式的请求,请参见上文介绍的使用php://input方式获取。

axios可以自定义请求头

// 实现axios异步上传图片
// 设置请求头为multipart/form-data
let post_config = {
  headers: {'Content-Type': 'multipart/form-data'}
};

function uploadImg(param) {
  return axios.post(地址, 发送的参数, post_config).then((res) => {
    return Promise.resolve(res.data);
  }).catch((err) => {
    return Promise.reject(err);
  });
}
// 请求头设置为application/x-www-form-urlencoded
let post_config = {
   headers: {'Content-Type': 'application/x-www-form-urlencoded'}
};

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:json格式的php获取、$_post
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    8513次阅读 542人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3553次阅读 265人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    13527次阅读 872人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12298次阅读 400人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    10694次阅读 858人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    14603次阅读 1162人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14420次阅读 1173人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    27770次阅读 2177人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    23986次阅读 1840人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录