深入浅出HTTP协议 - Ajax跨区访问的研究与实现(研一作品)

 

 最近一些天来,由于实验室项目开发的需要,自己对HTTP协议进行了比较细致的研究,并结合目前项目进度,成功解决了Ajax的跨域访问问题!

HTTP协议之深入浅出:

 HTTP-Hypertext Transfer Protocol(超文本传输协议),这是我们日常上网接触最多的网络应用层协议之一。有些朋友可能会问,这么个协议有什么值得研究的?非也,作为一个合格的软件开发人员,具备一定的协议分析能力是必要的,也是必须的,而且深入地理解HTTP协议也有助于我们掌握ServletJsp技术!

HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as "HTTP/1.1", and is an update to RFC 2068 [33].

下面,我们来看看Web中常用的术语,这对我们下面深入理解HTTP运行机理很有必要。浏览器(Browser)是Web应用的用户代理,它用于显示所请求的Web页面,并且提供了大量的导航功能和配置属性。因为Web浏览器是实现了HTTP协议的客户端,所以根据不同的上下文环境,我们经常交替使用“浏览器”和“客户机”来称呼它。目前流行的Web浏览器包括Netscape Communicator Microsoft Internet ExplorerWeb服务器用于存储Web对象(简单的说就是文件,如HTML文件,JPEG文件,GIF文件,Java小程序,声音剪辑文件等),每个对象由URL寻址(通常有两部分组成:存放对象的服务器主机名和对象的路径名)。Web服务器实现了HTTP的服务器端,流行的Web服务器程序有ApacheMicrosoft Internet Information ServerIIS)。

简单的讲,HTTP协议定义了浏览器如何向Web站点请求Web页面以及服务器如何响应请求这一过程。它是一种无状态的协议(Stateless),即服务器在向客户机发送响应消息时并不存储客户机的任何状态信息。

截至1997年,基本上所有的浏览器和服务器都实现的是在RFC 1945中定义的HTTP/1.0协议。从1998年开始,一些Web服务器和浏览器开始实现在RFC 2612中定义的HTTP/1.1 HTTP/1.1协议向后兼容HTTP/1.0协议,它最大的特点是支持持久连接。HTTP使用TCP(而不是UDP)作为底层传输协议。在TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。它不必像HTTP/1.0协议中定义的那样,为每一个请求对象建立和维护一个全新的连接。

持久连接又分为两种方式:非流水线方式(without pipelining)和流水线方式(with pipelining)。在非流水线方式下,客户机只能在前一个响应接收到之后才发出新的请求。在这种情况下,服务器发送完一个对象后,连接处于空闲状态,等待下一个请求的到来,这势必浪费了宝贵的服务器资源。

由于最近一直在做J2EE相关软件开发,所以在本次的研究中,我使用了业界最为流行的轻量级Web容器Tomcat(5.5.25版本)作为Web服务器,至于我前面提到的Apache,它比较适合用PHPWeb程序设计语言开发项目的Web服务器,而IIS则比较适合于Asp,Asp.net项目的Web服务器。当然,Tomcat在处理静态页面时速度显得稍微满了些,不过还好,我们可以讲TomcatApache或者是IIS进行集成,需要的仅仅是一个JK插件(这个插件我还没用过,所以不敢在这妄加评论,等以后项目中使用到了我想自己会认真研究一下,讲心得贴出来与大家分享!)。在这我们还是用到了Telnet客户端软件,这个软件默认是随着Window操作系统一起被装入机器的,唯一需要的是简简单单的一个Dos命令 net start telnet(当然这个命令是对于像我这种追求操作系统简约而停掉一些不经常使用的服务的人有用的,呵呵!)

在这,我要强调两个容易混淆的概念:URIURLURIUniform Resource Identifier),它是一套符号结构,用于标识Web资源的各个组成部分。URLUniform Resource Locator)是一种特殊的URI,它标识了用于查找某个资源足够的信息。而诸如:mailtofengjia11@163.com则不属于URL,我们只能称其为URN(Uniform Resource Name,通用资源名)。为了将讨论的重点放在其它上面,我们一般统称它们为URL

具体到HTTP报文的具体格式,我想在使用实例讲解,大家比较容易理解。Ok,看看我下面的截图。



 

 

下面,对照着截图,我们来一起看一下HTTP报文格式,HTTP协议是基于请求/响应模式的,请求报文的格式如下:请求行,消息报头(请求报头),请求正文。而请求行又有固定的格式,如上图第一行所示,其分别对应着:方法字段,URL字段,HTTP协议版本字段。在HTTP/1.0中,只有三类方法,分别为:GET,POST,HEAD。除了这三个方法外,在HTTP/1.1中还定义了其它的方法,诸如:PUT,DELETE,TRACE等。其中PUT方法是被那些需要上传对象到服务器端的应用程序所使用,当然编程人员也可以调用相关的API进行上传下载的编程,其底层就是使用了PUT方法。HEAD方法类似GET方法,当服务器收到HEAD方法的请求时,会用一个HTTP报文进行响应,但是不返回请求对象。应用程序开发人员常使用此方法进行故障跟踪。

由上图我们可以看出在请求行中我使用的HTTP/1.0版本的协议,而下面的一张截图中我使用了HTTP/1.1进行请求。两者的区别在于,后者必须有个Host消息报头字段,这是HTTP1.1做出的重大改进,它可以支持对服务器虚拟站点的访问,而这在HTTP/1.0中却是不可以的。并且注意:消息报头大小写无关(与请求行不同),并且在开发Servlet程序时,使用指令response.SetHeader()进行相关报头的设定。

好了,下面我们来看看响应报文的格式:状态行,消息报头(响应报头),响应正文。如图第三行所示。(第二行是一空行),其中200是状态代码,它由3个数字组成,表示请求是否被理解或被满足。状态代码的第一个数字定义了响应的类别,后面两个数字没有具体定义。由于篇幅的影响,这些代码具体代表的意思我就不详细叙述了,朋友们若有兴趣,可以参看RFC 2612文档说明。其中代码

200表示客户端请求成功。

400表示客户端请求有语法错误,不能被服务器理解。

401表示请求未经授权,这个错误在我在开发Asp程序时经常遇到,所以印象比较深刻。404表示请求的资源不存在。

500表示服务器发生不可预知错误,导致无法完成客户端请求。

503表示服务器当前不能处理客户端请求,稍后可能会恢复正常。



  

 

 

 

 

     到这,我想起了网络课上的Java编程,为了写好这篇文章,我又将当初成功编译运行的程序进行了修改(大约200多行吧!),本想把截图也贴出来,可是一想,由于博客无法上传图片,所以就放弃了当初的想法。奥,对了,这篇文章是我一口气写下来的,其中有些错别字可能没有纠正,不过自己会在以后的日子里继续修改的!还是那句话:“没有最好,只有更好!“

Ajax跨域访问

 Ajax技术中XHR对象其实可以理解为浏览器中的浏览器,它代替用户使用的浏览器向服务器发出请求,并获取数据,利用这一点我们可以直接读取远程网页,但事实远非如此简单,读取其他网站的请求属于跨域访问,对这种方式的访问,不同的浏览器可能会有所不同!对于IE 6 浏览器,会弹出如下图的的对话框,提醒用户要进行跨域访问,而FireFox对跨域访问根本就不会执行!


 

 

为了解决跨域访问的问题,可以在服务器端编写一个代理程序,XHR对象直接向代理程序发出请求,由代理程序访问远程服务器,并返回用户所需要的数据,这样就可以成功解决Ajax跨域访问的问题!

刚开始,自己动手进行代理程序的编写,解决了问题!后来发现,Apache Jakarta Commos下的子项目HtttpClient也可以解决此问题!

解决思路一:

自己动手编写Proxy程序,注意问题:

①字符串的拼接问题

②中文乱码问题

客户端与传统的Ajax不同之处在于字符串的拼接,当我们通过代理访问外域中的资源时,URL往往会拼接成这样:

http://127.0.0.1//AjaxServer?url=http://192.168.88.155/Ajax/index.jsp?username=fengjia&password=123

第一个问号前是目前Ajax程序所在的服务器地址,而我现在想访问师兄的机子上的某个页面,比方说index.jsp页面!很遗憾,这样的拼接服务器无法解析,必须将第二个问号也转换成&,为此,我们必须解决字符串拼接问题,具体代码如下图:



 

 

好了,我们看看服务器端是怎么实现的吧,实现思路如下:

    首先,要提取用户请求参数,对提交到同域下的请求和跨域下的URL请求要给予分别处理。

其次,根据服务器所接收参数的方式,决定使用GET或是POST方式生成新的请求字符串或请求体。当双方服务器对字符采用不同的编码时,还要进行字符编码的转换。

接下来,打开一个输入流,接收来自服务器的响应,并且分析响应头的内容,以确定对方对数据的处理是否成功完成,并且将处理结果返回给用户。

具体代码如下图:


 

解决思路二:使用HttpClient组件作为代理程序,代码如下:

String url = request.getParameter("url");

            HttpClient client = new HttpClient();

            GetMethod method = new GetMethod(url);

            try{

                client.executeMethod(method);

                out.println(method.getResponseBodyAsString());

            }catch(Exception e){

                method.releaseConnection();

            }

总结:

Ajax跨域访问是个比较复杂的问题,在具体的项目工作中,为了保证系统的健壮性,需要对多方面进行细致考虑,随着自己对Ajax技术的深入研究,技术日志会继续推新的!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值