网页、php脚本的编码问题

对于程序的编码问题,做一次总结,我们清楚,从对象来说,编码可能涉及到三到四个对象

一、首先是请求终端:

  这个请求终端有可能是浏览器端,从浏览器端发起网页请求;Ajax请求;也有可能是程序内部的Api调用。

    

  a、先看浏览器端和web服务器端的数据交互采用的编码符合什么准则

        浏览器端的输入分成两种情况,
        第一种情况是:在浏览器的地址栏输入url地址,在带有汉字的情况下的编码选择,这种情况是没有指定传输编码,测试中发现,IE,firefox,chrome会将地址栏中

浏览器  默认传输编码
IE gbk
firefox     utf-8
chrome      utf-8

   
        第二种情况是:在网页中输入的汉字,再和服务器交互过程中的编码选择
            这种情况的汉字传输编码,会和网页设置的编码有关。如果charset是gbk,则以gbk形式传递参数。    

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
</head>

 

    b、Ajax请求

        实际上ajax请求和第一种情况,从地址栏输入url发起请求一样,实际上都是未指定请求参数的编码,在这种情况下,

    c、php程序内部的Api请求

        我们在php程序中会使用到curl或者简单的使用file_get_contents()方法去调用Api,在调用过程中,我们会带上参数。如果这个参数是汉字
        那么出现两种情况
        情况一,参数是外界输入
        情况二,参数是脚本定义的

        我们写个简单的实验看一下,首先,我们写一个脚本testcode.php,采用GBK编码保存  

<?php

    if(isset($_REQUEST['m'])){
        $pram1 = $_REQUEST['m'];
    }
    
    $pram2 = "你好";
    $filename = "http://10.221.20.175/test/example.php?p1=$pram1&p2=$pram2";
    $s = file_get_contents($filename);
    
    var_dump($s);

  脚本2 example.php 采用UTF-8保存只是输出值

<?php

    if(isset($_REQUEST['p1'])){
        echo  $_REQUEST['p1'];
    }
    else{
        echo  "p1."; 
    }
    
    if(isset($_REQUEST['p2'])){
        echo  $_REQUEST['p2'];
    }
    else{
        echo  "p2."; 
    }    

  

  我们在浏览器端请求 http://10.221.20.175/test/testcode.php?m=达人

 

 

从图中,我们一步一步查看。
        1、第一步,服务端抓包,可以看出,参数“达人”被转码,转成了%E8%BE%BE%E4%BA%BA, 实际上,汉字”达人“是被
            转成了UTF8编码,编码的每个字节前用"%"做了标识 

    

       2、第二步,web服务器和php-fpm交互,LNNP环境下,一般会启动php-fpm和nginx做交互,可以看到,交互中,nginx未修改汉字"达人"的编码  

 

         3、第三步,testcode.php脚本被php引擎读入,发现file_get_contents,需要请求链接,再发起请求到nginx服务器。我们能看到 这个请求链接包含两个参数 /test/example.php?p1=......&p2=.... ,很明显,从脚本看,p1这个参数是UTF8编码,p2这个参数是gbk编码。   

 

   4、第四步,nginx请求处理file_get_contents请求,将请求转给php-fpm

 

         5、第五步,php引擎接到第四步的请求,读入example.php脚本处理,我们看一下,处理的返回值。返回的字符串编码是 e8be bee4 baba c4e3 bac3 明显看出来,前面是三个字节是utf8编码,表示“达人”,后面两个是gbk编码表示“你好”

  

  6、第六步,nginx在收到第五步的返回值后,会将结果返回给testcode.php脚本处理程序,我们可以看出,返回结果被放在610d0a字符编码后,基本在最后,结束符编码是0d 0a30 0d0a 0d0a
   

     7、第七步、 testcode.php脚本在处理完后,会将结果返回给nginx服务器,返回处理值中,对于脚本的返回值,做了gzip压缩,这主要是因为在请求头上有接受gzip压缩是否可以看出,请求头上的是否接受压缩,是php引擎做的?

 

  8、第八步、nginx服务器和客户端交互,在这里,实际上返回值被gzip压缩了。所以看不到传递的值,但是从客户端解压缩后,我们可以看到,显示的结果和第7步返回给nginx的是一致的。

 

   
       从上面的情况,我们大概能得到这样的结论:
       这个结论是建立在简单的实验基础上,未参照php源码,可能会有不一致的地方,但是,不管怎么样,我们可以认为,
       1、在php程序中,如果不采用转码函数,如,iconv()等,那么php本身不会自动将输入参数转成代码本省的参数
       2、在php程序中,程序内部定义的汉字,按照程序保存时候的编码传递。

 

posted @ 2014-12-15 17:11  壹木人  阅读(351)  评论(0编辑  收藏  举报