自己写了一个php的socket http请求,
public function sendpost($postType='POST')
{
$url = $this->postURL;
$data = $this->postData == '' ? array() : $this->postData;
//先解析url
$url = parse_url($url);
$url_port = !isset($url['port']) ? (($url['scheme'] == 'http') ? 80 : 443) : $url['port'];
if (!$url)
{
$this->errMessage = "couldn't parse url";
return false;
}
//将参数拼成URL key1=value1&key2=value2 的形式
$encoded = "";
while (list($k, $v) = each($data))
{
$encoded .= ($encoded ? '&' : '');
$encoded .= rawurlencode($k)."=".rawurlencode($v);
}
//echo $encoded;exit;
$len = strlen($encoded);
//拼上http头
$out = "{$postType} ".$url['path'].(isset($url['query']) ? ('?'.$url['query']) : '')." HTTP/1.1\r\n";
$out .= "Host:".$url['host']."\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n";
$out .= "Content-Length: $len\r\n";
$out .= "\r\n";
$out .= $encoded."\r\n";
//打开一个sock
$fp = @fsockopen($url['host'], $url_port);
$line = "";
if (!$fp)
{
$this->errMessage = "$errstr($errno)\n";
return false;
}
else
{
fwrite($fp,$out);
while (!feof($fp))
{
$line .= fgets($fp, 2048);
}
}
//去掉头文件
if ($line)
{
$body = stristr($line, "\r\n\r\n");
$body =substr($body, 4, strlen($body));
$line = $body;
}
fclose($fp);
return $line;
}
同时,用jquery的ajax请求测试。
$.ajax({
type : "POST",
cache : false,
url : _url,
data : _data,
dataType : 'json',
success : function(data) {

}
});
发现php的请求总是返回错误的信息,而ajax请求则返回正确的,应该都是http post请求数据返回数据,没什么区别吧。
服务器端还可以检测出是ajax请求还是php请求?

解决方案 »

  1.   

    [User:root Time:03:17:09 Path:/home/apache/web]$ cat test.php 
    <?php
    // http only, no error check.
    function post_request($url, $data) {
            $post_data = http_build_query($data);
            $request = "POST /main.php HTTP/1.1\r\n" . 
                               "Host: 192.168.1.10\r\n" .
                               "Content-Type: application/x-www-form-urlencoded\r\n" .
                               "Content-Length: " . strlen($post_data) . "\r\n\r\n" .
                               $post_data;
            echo $request . PHP_EOL;
            $sockfd = fsockopen("192.168.1.10", 80);
            fwrite($sockfd, $request);
            $response = "";
            while (($ret= fgets($sockfd)) !== false) {
                    $response .= $ret;
            }
            return $response;
    }$response = post_request("http://192.168.1.10/main.php", array('a' => "baidu", 'b' => "client backend"));
    echo $response;
    ?>
    [User:root Time:03:17:12 Path:/home/apache/web]$ cat main.php 
    <?php
    echo $_POST['a'] . PHP_EOL;
    echo $_POST['b'] . PHP_EOL;
    ?>不知道你错在哪,代码太短了。
      

  2.   

    另外,https你的代码是无力的,必须用php支持的context参数利用stream_context_create配合file_get_contents之类的使用或者fopen之类的使用,或者直接用curl。
      

  3.   

    错,刚才看了一下,fsockopen支持SSL和TSL,这样:
    hostname
    If OpenSSL support is installed, you may prefix the hostname with either ssl:// or tls:// to use an SSL or TLS client connection over TCP/IP to connect to the remote host.
      

  4.   

    嗯,本来想分别抓包对比一下,想想还是算了,先用curl试试