使用PHP进行异步HTTP请求

使用JavaScript/Ajax可轻松实现异步HTTP请求,本文介绍使用PHP进行异 步HTTP请求。所谓异步HTTP请求是指:HTTP协议基于TCP且是基于状态的,client和server建立 连接后发送请求需要等到server处理结束并返回后才可以断开连接。某些情况下,client端只需要发出自己的请求即可,不需要知道 server端的响应,这个时候即需要实现client端发出异步HTTP请求。另外,在长耗时应用中(请求的server端任务比较 耗时,超过HTTP timeout时间甚至更长),也可以考虑使用异步HTTP请求出发该任务。关于长耗时应用也可以参考该文

方法1:使用curl的CURLOPT_TIMEOUTCURLOPT_TIMEOUT_MS

设置CURLOPT_TIMEOUT为最小值1,client端在等待1秒之后即返回。

    $url = "http://www.yoursite.com/background-script.php";
    $ref_url = "http://www.yoursite.com";
    $data = array(
        "key1" => "value1",
        "key2" => "value2",
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_REFERER, $ref_url);

    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);        

    curl_setopt($ch, CURLOPT_TIMEOUT, 1);

    curl_exec($ch);
    curl_close($ch);

如果是cURL 7.16.2 or higher and PHP 5.2.3 or above,可以设置Timeout时间为1 ms,实现立即返回,修改如上的curl_setopt($ch, CURLOPT_TIMEOUT, 1);curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);

方法2:使用socket修改HTTP header

使用socket连接到server上,发送raw HTTP header(注意设置Connection: Close), 完成之后立即关闭socket不等待server做出响应再返回。

GET例子

需要请求的server url为http://example.com/Default.aspx,接受的参数为action=start,method 为GET,需要携带的cookies为ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah。(这 些信息都可以使用HttpWatch分析得到)。

例如HttpWatch的分析的client端的HTTP请求为:

    GET /Default.aspx?action=start HTTP/1.1
    Accept-Language: zh-cn
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)
    Accept-Encoding: gzip, deflate
    Host: example.com
    Connection: Keep-Alive
    Cookie: ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah

修改为异步HTTP请求:

    <?php

    $host = "example.com";
    $path = "/Default.aspx?action=start";
    $cookie = "ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah";

    $start = microtime(true);

    $fp = fsockopen($host, 80, $errno, $errstr, 30);
    if (!$fp) {
       print "$errstr ($errno)<br />\n";
       exit;
    }
    $out = "GET ".$path." HTTP/1.1\r\n";
    $out .= "Host: ".$host."\r\n";          //需要注意Host不能包括`http://`,仅可以使用`example.com`
    $out .= "Connection: Close\r\n";
    $out .= "Cookie: ".$cookie."\r\n\r\n";

    fwrite($fp, $out);  //将请求写入socket

    /*
    //也可以选择获取server端的响应
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    */

    //如果不等待server端响应直接关闭socket即可
    fclose($fp);

    $cost = microtime(true) - $start;
    print "\n".$cost."\n";
    exit;
POST例子

需要请求的server url为http://example.com/Login.aspx,接受的参数为username=my-username&password=my-password,method 为POST,需要携带的cookies为ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah。(这 些信息都可以使用HttpWatch分析得到)。

例如HttpWatch的分析的client端的HTTP请求为:

    POST /Login.aspx HTTP/1.1
    Accept-Language: zh-cn
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)
    Content-Type: application/x-www-form-urlencoded
    Accept-Encoding: gzip, deflate
    Host: example.com
    Connection: Keep-Alive
    Cache-Control: no-cache
    Cookie: ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah

    username=my-username&password=my-password

修改为异步HTTP请求:

    <?php

    $host = "example.com";
    $path = "/Login.aspx";
    $cookie = "ASP.NET_SessionId=zfyaimqgtt1bfiewq0najgah";
    $params = "username=my-username&password=my-password";

    $start = microtime(true);

    $fp = fsockopen($host, 80, $errno, $errstr, 30);
    if (!$fp) {
       print "$errstr ($errno)<br />\n";
       exit;
    }
    $out = "POST ".$path." HTTP/1.1\r\n";
    $out .= "Host: ".$host."\r\n";
    $out .= "Connection: Close\r\n";
    $out .= "Cookie: ".$cookie."\r\n\r\n";
    $out .= $params;

    fwrite($fp, $out);  

    /*
    //也可以选择获取server端的响应
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    */

    //如果不等待server端响应直接关闭socket即可
    fclose($fp);

    $cost = microtime(true) - $start;
    print "\n".$cost."\n";
    exit;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,你可以参考以下的代码实现: HTML代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>注册账号</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <h1>注册账号</h1> <form id="register-form"> <label for="username">用户名:</label> <input type="text" id="username" name="username"><br> <label for="password">密码:</label> <input type="password" id="password" name="password"><br> <label for="email">邮箱:</label> <input type="text" id="email" name="email"><br> <button type="submit">注册</button> </form> <div id="result"></div> <script src="register.js"></script> </body> </html> ``` JavaScript代码: ```javascript $(function() { // 监听表单提交事件 $('#register-form').submit(function(event) { // 阻止默认表单提交事件 event.preventDefault(); // 获取表单数据 var formData = { 'username': $('input[name=username]').val(), 'password': $('input[name=password]').val(), 'email': $('input[name=email]').val() }; // 发送异步请求 $.ajax({ type: 'POST', url: 'register.php', dataType: 'json', data: formData, encode: true }) .done(function(data) { // 注册成功 $('#result').html('<p>' + data.message + '</p>'); // 清空表单 $('#register-form')[0].reset(); }) .fail(function(data) { // 注册失败 $('#result').html('<p>' + data.responseJSON.message + '</p>'); }); }); }); ``` PHP代码: ```php <?php // 模拟注册逻辑 if ($_SERVER['REQUEST_METHOD'] == 'POST') { $username = $_POST['username']; $password = $_POST['password']; $email = $_POST['email']; // 判断用户名是否已存在 if ($username == 'admin') { http_response_code(400); echo json_encode(array('message' => '用户名已存在')); } else { // 注册成功 echo json_encode(array('message' => '注册成功')); } } ``` 在这个例子中,我们使用了 jQuery 库来简化异步请求的代码。当用户在前端页面填写完注册信息后,点击注册按钮,前端代码会将表单数据通过 Ajax 异步请求发送到后端 PHP 脚本,PHP 脚本模拟了注册逻辑,如果注册成功,会返回一个 JSON 数据,前端代码会根据返回的数据提示用户注册成功,同时清空表单;如果失败,会返回一个错误消息,前端代码会根据错误消息提示用户注册失败。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值