zoukankan      html  css  js  c++  java
  • AJAX POST请求中参数以form data和request payload形式在php中的获取方式

    一.MINE TYPE问题:

    php对mime type为“application/x-www-form-urlencoded”(表单提交)和“multipart/form-data”(文件上传)的Post请求的数据作特殊处理

    下面以“multipart/form-data”为例对源码进行解析:

    当客户端发起文件提交请求时,Apache会将所接收到的内容转交给mod_php5模块。 当PHP接收到请求后,首先会调用sapi_activate,在此函数中程序会根据请求的方法处理数据,如示例中POST方法,其调用过程如下:

    sapi_read_post_data在main/SAPI.c中实现,它会根据POST内容的Content-Type类型来选择处理POST内容的方法:

    以上代码的关键在于SG(known_post_content_types)变量, 此变更是在SAPI启动时初始化全局变量时被一起初始化的,其基本过程如下:

    这里的的php_post_entries定义在main/php_content_types.c文件。如下:

    如上所示的MULTIPART_CONTENT_TYPE(multipart/form-data)所对应的rfc1867_post_handler方法就是处理$_FILES的核心函数, 其定义在main/rfc1867.c文件:SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) 后面获取Content-Type的过程就比较简单了:

    • 通过multipart_buffer_eof控制循环,遍历所有的multipart部分
    • 通过multipart_buffer_headers获取multipart部分的头部信息
    • 通过php_mime_get_hdr_value(header, “Content-Type”)获取类型
    • 通过register_http_post_files_variable(lbuf, cd, http_post_files, 0 TSRMLS_CC); 将数据写到$_FILES变量。

    main/rfc1867.c

    其它的$_FILES中的size、name等字段,其实现过程与type类似。

    二.   原生ajax请求不指定MINE TYPE默认都是text/plain(method:POST),chrome调试工具抓包显示:

    如果指定 headers: {‘Content-Type’: ‘application/x-www-form-urlencoded’},则显示如下:

    三.如果post请求MINE TYPE不是application/x-www-form-urlencoded或multipart/form-data,php不作处理,要获取数据只能去读取原生态的输入流php://input

    比如用$.ajax方法发送请求时(data参数是一个JSON.stringify()处理后的字符串,而不是一个JSON对象):account_pay_money=0&real_cash_money=80&uid=1191&saveInStore=1&direct_cash=1&projects%5B0%5D%5Bgoods_id%5D=13&projects%5B0%5D%5Bgoods_num%5D=1&projects%5B0%5D%5Bprice%5D=80.00&projects%5B0%5D%5Btech_ids%5D%5B%5D=1029&vt=1441977345904&lsid=1

    如果用$.post方法来发送请求(data参数是一个JSON对象,而不要再用JSON.stringify()处理为字符串了)

    这个两种数据处理如下:

    总结:

    服务器为什么会对表单提交和文件上传做特殊处理,因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的post请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。

    jquery在执行post请求时,会设置Content-Type为application/x-www-form-urlencoded,所以服务器能够正确解析,而使用原生ajax请求时,如果不显示的设置Content-Type,那么默认是text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据。

  • 相关阅读:
    修复PLSQL Developer 与 Office 2010的集成导出Excel 功能
    Using svn in CLI with Batch
    mysql 备份数据库 mysqldump
    Red Hat 5.8 CentOS 6.5 共用 输入法
    HP 4411s Install Red Hat Enterprise Linux 5.8) Wireless Driver
    变更RHEL(Red Hat Enterprise Linux 5.8)更新源使之自动更新
    RedHat 5.6 问题简记
    Weblogic 9.2和10.3 改密码 一站完成
    ExtJS Tab里放Grid高度自适应问题,官方Perfect方案。
    文件和目录之utime函数
  • 原文地址:https://www.cnblogs.com/winyh/p/7911204.html
Copyright © 2011-2022 走看看