用PHP模拟HTTP中的POST请求JSP网页,提交数据

今天我们来实现一个提交话费的WEB程序,主要应用在:代理电信公司话费交纳。

第一步:获取登录页面的SESSION会话ID值.

     为什么要获取SESSION值?

2010102916391076.jpg

     我们知道,用户访问一个网站时往往需要浏览许多网页。对于一个通过PHP构筑的网站来说,用户在访问的过程中需要执行许多的动态页面(如:jsp、PHP、APS.NET等)。然而由于HTTP协议自身的特点,用户每执行一个动态页面,都需要和Web服务器重新建立连接。

     又由于WEB程序无状态记忆的特点,此次连接无法得到上次连接的状态。这样,用户在一个动态页面中对一个变量进行了赋值操作,而在另外一个动态页面中却无法得到这个变量的值。例如,用户在负责登录的动态页面中设置了string username = "wind",却无法在另一个动态页面中通过调用 username 来获得“wind”这个值。也就是说,在程序中无法设置全局变量。也就是说:  每个动态脚本中所定义的变量都是只在这个脚本内有效的局部变量。 

     Session解决方案,就是要提供在动态脚本中定义全局变量的方法,使得这个全局变量在同一个Session中对于所有的动态页面都有效。上面我们提到了,Session不是一个简单的时间概念,一个Session中还包括了特定的用户和服务器。因此更详细地讲,在一个Session定义的全局变量的作用范围,是指这个Session所对应的用户所访问的所有动态脚本。

    又因为HTTP协议是一种无状态链接方式,也就是说服务端与客户端不是链接在一起的。HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。(我们称这个客户端)叫用户代理(user agent)。应答的服务器上存储着(一些)资源,比如HTML文件和图像。(我们称)这个应答服务器为源服务器(origin server)。

2010102916464840.jpg

    在用户代理和源服务器中间可能存在多个中间层,比如代理,网关,或者隧道(tunnels)。尽管TCP/IP协议是互联网上最流行的应用,HTTP协议并没有规定必须使用它和(基于)它支持的层。 事实上,HTTP可以在任何其他互联网协议上,或者在其他网络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使用。

下面是用PHP实现的HTTP中的POST请求代码:
 
   
1 /* *
2 * Post 方式请求网页数据
3 *
4 * @param string $url 网页地址
5 * @prarm string $host 主机
6 * @param string $session 会话值
7 * @prarm string $type 类型(POST、GET)
8 * @prarm string $port 端口
9 * @prarm string $data 数据
10 */
11 function getPageConent( $url , $host , $session = "" , $type = " POST " , $port = "" , $data = "" ) {
12
13 if ( empty ( $port ) ) $port = 80 ;
14
15 /* 请求数据 */
16 $post_data = $data ;
17 $lenght = strlen ( $post_data );
18
19 $headers = " { $type } { $url } HTTP/1.1\r\n " ;
20 $headers .= " Accept: * /*\r\n " ;
21 $headers .= " Content-Type: application/x-www-form-urlencoded\r\n " ;
22 $headers .= " User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; CIBA; .NET CLR 4.0.20506)\r\n " ;
23 if ( $session != "" ) $headers .= " Cookie:JSESSIONID={ $session }\r\n " ;
24 $headers .= " Host: { $host }:{ $port }\r\n " ;
25 $headers .= " Content-Length: { $lenght }\r\n " ;
26 $headers .= " Connection: Close\r\n\r\n " ;
27 $headers .= $post_data ;
28
29 if ( $fp = fsockopen ( $host , $port , $errno , $errstr , 100 ) ) {
30 fwrite ( $fp , $headers );
31 $header = fread ( $fp , 1024 );
32 $content = fread ( $fp , 1024 );
33 $content .= fread ( $fp , 1024 );
34 $content .= fread ( $fp , 1024 );
35 $content .= fread ( $fp , 1024 );
36 fclose ( $fp );
37 }
38 if ( $data != "" ) {
39 echo $headers ;
40 echo " <hr /> " ;
41 echo $header ;
42 echo " <hr /> " ;
43 echo $content ;
44 echo " <hr /> " ;
45 exit ;
46 } else {
47 return $content ;
48 }
49 }

下面是获取网页代码的程序

 
   
1
2   /* *
3 * 获取URL地址内容
4 *
5 * @param string $url 地址
6 *
7 * @return mixed
8 */
9
10 function getUrlContent( $url ) {
11
12 $url_parsed = parse_url ( $url );
13 $host = $url_parsed [ ' host ' ];
14 $port = $url_parsed [ ' port ' ];
15
16 /* Port */
17 if ( $port == 0 ) {
18 $port = 80 ;
19 }
20
21 /* Path */
22 $path = $url_parsed [ ' path ' ];
23 if ( empty ( $path )) {
24 $path = " / " ;
25 }
26
27 /* query */
28 if ( $url_parsed [ ' query ' ] != "" ) {
29 $path .= " ? " . $url_parsed [ ' query ' ];
30 }
31
32 /* Open Page Content */
33 $out = " GET { $path } HTTP/1.0\r\nHost: { $host }\r\n\r\n " ;
34 if ( $fp = @ fsockopen ( $host , $port , $errno , $errstr , 30 )) {
35 fwrite ( $fp , $out );
36 $header = fread ( $fp , 1024 );
37 fclose ( $fp );
38 return $header ;
39 } else {
40 return false ;
41 }
42 }
下面是实现POST返回值编码的代码
 
   
1 /* *
2 * HTTP 编码定义
3 */
4 if ( ! function_exists ( ' http-chunked-decode ' )) {
5 function http_chunked_decode( $chunk ) {
6 $pos = 0 ;
7 $len = strlen ( $chunk );
8 $dechunk = null ;
9
10 while (( $pos < $len )
11 && ( $chunkLenHex = substr ( $chunk , $pos , ( $newlineAt = strpos ( $chunk , " \n " , $pos + 1 )) - $pos )))
12 {
13 if ( ! is_hex( $chunkLenHex )) {
14 trigger_error ( ' Value is not properly chunk encoded ' , E_USER_WARNING );
15 return $chunk ;
16 }
17
18 $pos = $newlineAt + 1 ;
19 $chunkLen = hexdec ( rtrim ( $chunkLenHex , " \r\n " ));
20 $dechunk .= substr ( $chunk , $pos , $chunkLen );
21 $pos = strpos ( $chunk , " \n " , $pos + $chunkLen ) + 1 ;
22 }
23 return $dechunk ;
24 }
25 }
26
27   /* *
28 * 判断一个字符串可以代表十六进制的一个电话号码
29 *
30 * @param string $hex
31 * @return boolean true if the string is a hex, otherwise false
32 */
33 function is_hex( $hex ) {
34 /* 正则表达式是思想 */
35 $hex = strtolower ( trim ( ltrim ( $hex , " 0 " )));
36 if ( empty ( $hex )) { $hex = 0 ; };
37 $dec = hexdec ( $hex );
38 return ( $hex == dechex ( $dec ));
39 }
40  
将验证码图片存储在本地
 
   
1
2 /* *
3 * 存储图片
4 */
5 function SaveImgage( $content , $dir = " img.png " ) {
6 $content = http_chunked_decode( $content );
7
8 $con = fopen ( $dir , " w " );
9 fwrite ( $con , $content );
10
11 fclose ( $con );
12 return $dir ;
13 }
下面是具体的实现代码
 
   
1
2 /* 操作PHP代码 */
3 if ( $_POST [ ' Action ' ] == ' ok ' ) {
4
5 $txtpPhone = $_POST [ ' txtpPhone ' ];
6 $txtMoney = $_POST [ ' txtMoney ' ];
7 $txtType = $_POST [ ' txtType ' ];
8
9 /* post data */
10 $AGENTS_LOGIN_TYPE = " AG2 " ;
11 $AG2_agentNumber = " ************* " ;
12 $AG2_agentPassword = " ********* " ;
13 $logon_valid = $_POST [ ' txtcode ' ];
14 $SessionId = $_POST [ ' SessionId ' ];
15 $LOGIN = "" ;
16
17 $postData = " LOGINS=LOGIN_IN&AGENTS_LOGIN_TYPE={ $AGENTS_LOGIN_TYPE }&AG2_agentNumber={ $AG2_agentNumber }&AG2_agentPassword={ $AG2_agentPassword }&logon_valid={ $logon_valid }&JSESSIONID={ $SessionId } " ;
18
19 $img = getPageConent( " /agent/login.jsp " , " www.gz.ct10000.com " , $SessionId , " POST " , " 80 " , $postData );
20
21 echo $img ; exit ;
22
23 } else {
24 $str = getUrlContent( " http://www.gz.ct10000.com/agent/index.jsp " );
25
26 $preg = ' /JSESSIONID=(.*);/isU ' ;
27 preg_match_all ( $preg , $str , $match );
28 $SessionId = $match [ 1 ][ 0 ];
29
30 $coding = getPageConent( " /public/image.jsp " , " www.gz.ct10000.com " , $SessionId );
31 $img = SaveImgage( $coding );
32 }
33   ?>
34   <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
35   < html xmlns = " http://www.w3.org/1999/xhtml " >
36   < head >
37   < meta http - equiv = " Content-Type " content = " text/html; charset=utf-8 " />
38   < title > 用户交话费 </ title >
39   </ head >
40   < body >
41 < form aaction = " index.php " method = " post " enctype = " application/x-www-form-urlencoded " name = " form1 " id = " form1 " >
42 < input type = " hidden " name = " SessionId " id = " SessionId " value = " <?= $SessionId ?> " />
43 < input type = " hidden " name = " Action " id = " Action " value = " ok " />
44 < span id = " Label1 " > 输入验证 </ span >< input name = " txtcode " type = ' text ' id = " txtcode " />< img src = " img.png " alt = " aa " />< br >
45 < span id = " Label1 " > 电话号码 </ span >< input name = " txtpPhone " type = " text " id = " txtpPhone " />< br />
46 < span id = " Label3 " > 充值金额 </ span >< input name = " txtMoney " type = " text " id = " txtMoney " />< br />
47 < span id = " Label2 " > 电话类型 </ span >< input name = " txtType " type = " text " id = " txtType " />< br />
48 < input type = " submit " name = " Button1 " value = " 提交 " id = " Button1 " />
49 </ form >
50   </ body >
51 </ html >

原创作者:Tiwer
文章出处:http://wgw8299.cnblogs.com/
关于作者:专注于互联网技术研究与开发、企业信息化解决方案。现主要从事PHP, WinForm、ASP.NET、JavaScript、UI、CSS、Linux/Uinx、C++,Google Android等方面的项目开发、架构工作。
版权说明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。


转载于:https://www.cnblogs.com/wgw8299/archive/2010/10/29/1864596.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值