总结得不错。

1、按钮为button,可在js中调用formName.submit()显性提交。若是submit按钮,则不能再这样加提交语句,否则会提交两次。

2、一个input域中回车,会默认第一个submit属性的按钮提交。若都是butoon属性,则回车不会提交表单。

3、有时提交表单后不能刷新页面,即没有action=""的情况,<form name="hand" method="post" onSubmit="javascript:return handle();">(此时在handle()中进行处理后会返回一个false)或者<form name="hand" method="post" onSubmit="javascript:handle();return false">或者<input type="button" id="addbt" name="addbt" value="增加关联" onClick="javascript:subList();return false;" />。这样做了后能保证只执行js代码后,本页面不刷新,也不提交到另一个页面。

//一般提交 
function del(myform) 

myform.target="_blank" //也可以是_self,_top,_parent,默认为_self 
myform.action="trade_delete.asp"; 
myform.submit();  


//提交后对窗口的限制 
function del(creator) 

creator.target="preview"; 
creator.action="register_check.asp"; 
var win = window.open("about:blank","preview","toolbar=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=250,height=25,top=250,left=300"); 
win.focus(); 
creator.submit(); 

 

 

 

  • 总结下这么几种的方法:   
  • 1,通过type=submit 或者图片的submti来提交(图片的这种方法很不错)   
  • 2,通过在imput里面加onclick来写个方法来做提交前的验证.type可以是button.,反正多个浏览器  
  •    做的时候,试验一下.   
  • 3,还有可以通过在form里面加onsubmit来验证.   
  • 4,通过在javascript的方法里头,用submit()方法来提交   
  •   具体得到这个form的方法有:   
  • oForm = document.getElementById("form1");   
  • oForm = document.forms("form1");   
  • oForm = document.forms[0];   
  • //通过上面的几种可以得到form   
  • oForm.submit(); 
  • xml 代码
    1. <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>  
    2. <html>  
    3. <script type="text/javascript">  
    4.     function dosubmit() {   
    5.         alert("heihei");   
    6.     }   
    7. script>  
    8. <head>javascript测试head>  
    9. <body>  
    10.        
    11. <hr>  
    12.     <form action="print.jsp" method="post">  
    13.          <input type="text" name="hello"/>  
    14.          <input type="submit" name="sub" value="提交" onclick="dosubmit()"/>  
    15.            
    16.     form>  
    17. body>  
    18. html>  

    可以在函数里面做出验证.

    这个要用onclick 来触发事件,onchange,试了下不行其他不行.

    这里是用按钮.这里type用了submit

    xml 代码
    1. <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>  
    2. <html>  
    3. <script type="text/javascript">  
    4.     function dosubmit() {   
    5.         document.forms[0].submit();   
    6.         alert("^_^提交成功!");   
    7.     }   
    8. script>  
    9. <head>javascript测试head>  
    10. <body>  
    11.        
    12. <hr>  
    13.     <form action="print.jsp" method="post">  
    14.          <input type="text" name="hello"/>  
    15.          <input type="button" name="sub" value="提交" onclick="dosubmit()"/>  
    16.            
    17.     form>  
    18. body>  
    19. html>  

     这里type用button,用document.forms[0].submit()来提交.

    xml 代码
    1. <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>  
    2. <html>  
    3. <script type="text/javascript">  
    4.     function dosubmit() {   
    5.         //document.forms[0].submit();   
    6.         alert("1111提交成功!");   
    7.     }   
    8. script>  
    9. <head>javascript测试head>  
    10. <body>  
    11.        
    12. <hr>  
    13.     <form action="print.jsp" method="post">  
    14.          <input type="text" name="hello"/>  z
    15.          <input type="image"  src="submit.bmp" name="sub" onclick="dosubmit()"/>  
    16.            
    17.     form>  
    18. body>  
    19. html>  
    20. <form name="form1" method="post" action="<%=request.getContextPath()%>/news/NewsTypeAddAction.sh"

      onSubmit="return actionCheck();">


      <table>
      <tr>
      <td>新闻类型编号</td>
      <td>
      <input type="text" name="typeid" onBlur="isDigit(this.value)"> </td>
      </tr>
      <tr>
      <td>新闻类型名称</td>
      <td>
      <input type="text" name="typename"> </td>
      </tr>
      <tr>
      <td>新闻存放目录名称</td>
      <td>
      <input type="text" name="dir"> </td>
      </tr>
      <tr>
      <td>使用模版名称</td>
      <td>
      <input type="text" name="templatename"> </td>
      </tr>
      <tr>
      <td colspan="2">
      <div align="center">
      <input type="submit" name="Submit" value="Submit">
      <input type="reset" value="Reset"> 
      </div></td>
      </tr>
      </table>
      </form>
      <script type="text/javascript">
      function isDigit(s)
      {
      var patrn=/^[0-9]{1,20}$/;
      if (!patrn.exec(s)&&s!=""){
      alert("请您输入数字!");
      document.form1.typeid.value="";
      document.form1.typeid.focus();
      return false;
      }
      }

      function actionCheck()
    21. {
           if(document.form1.typeid.value=="")
    22.      {
                 alert("新闻类型编号不能为空!");
                 document.form1.typeid.value="";
                  document.form1.typeid.focus();
                  return false;
      }
      }
      </script>
    posted @ 2011-11-23 19:32 小马歌 阅读(2114) | 评论 (0)编辑 收藏
     
    posted @ 2011-11-19 12:58 小马歌 阅读(348) | 评论 (0)编辑 收藏
     

    简介

      一般使用源应用的API接口,或者是一些rss输出(含atom)作为内容源,合并的web应用用什么技术,则没有什么限制。mashup在geek群体和互联网玩家之中获得了极大的欢迎,mashup未必需要很高的编程技能,只需要熟悉api和网络服务工作方式,都能进行开发,所以很快成为一个流行的网络现象。很多公司例如yahoo/google都为此提供开放接口,以吸引这个群体。
      Mashup 是一个非常cool的新的应用程序种类。如果你想真正的了解它们,我们需要回过头来看看你现在的计算机,其实它就是一个非常好的帮助你理解Mashup的模型。计算机运行着操作系统,例如Windows。现在开源的操作系统无疑是一个非常好的APIs 的集合或者一个应用程序编程接口,帮助开发者去构建他们的应用程序。计算机本身也是一个很好的为用户提供接口的例子,键盘和鼠标可以被理解为你通过计算机的接口而使用的不同的应用程序。
      

    Mashup

    一个API可能是帮助电脑接入网络又或者用来提供显示功能。总之,这些APIs 帮助开发者更加容易的去构建他们的应用程序。在过去开发者需要描绘每一个点显示的位置,而现在仅仅需要给出对称坐标,就可以完成一个窗口的绘制。
      APIs做的事情是这样的。假如你访问文件系统,那么你所需得到APIs,这是计算机工作的途径。然后你就可以在一个窗口里运行一个应用程序。人们开发一个应用程序通常需要3或4个不同的APIs,或许更多。

    编辑本段运行方式

      这是一个计算机传统的运行方式。现在,我们将Windows,操作系统替换成网络。那么同样的,就会有许多公司来提供哪些APIs。比如yahoo,google.例如一个叫EVDB的公司,它是一个事件日历的数据库,可以提醒你什么时间到哪里做什么事情。也包括像 Amazon 和 eBay,又比如Technorati ,所有这些不同的公司把APIs放到网上使开发者可以访问。
      现在假如你是一个Web开发者,你通过一个API 找到你附近哪些地方会有犯罪。然后你访问Google 地图API,把这两个内容整合在一起,那么你就得到了一个标有犯罪纪录的地图。这个新的地图就叫Mashup。因为开发者通过来自多个网站的APIs,把他们合并在一起,成为了一个新的很cool的应用程序。

    编辑本段目前

      越来越多的APIs被开放,这是一个比较明确的方向,每天都会有大概2.5个Mashup产生,预计到2007年每天Mashup的产生数量会增加到10个。
      之所以,一天会有10个Mashup产生是因为,开发将会变得越来越容易,你不用再必须变成一个C语言程序员去展示你的创造力,你可以开发很Cool的应用,例如哪里有停车空位的地图,就像在California得Bay 地区的 ParkingCarma 所做的那样。又或者你开发一个地图标记出你的邻居和你想去会见某人,这其实也已经是一个事实存在的应用了,FrozenBear公司正在做这方面的开发。
      我们展示这些Mashup的同时,又有新的APIs随时发布到网上,这就形成了一个生态系统,而且这个生态系统比目前现存的所有生态系统都会增长的更快。Windows,你必须成为一个程序员才可以开发应用程序,Linux,Macintosh也同样是如此,但是Mashup却不必, 它将会是今天增长速度最快的一个生态体统。

    编辑本段发展

      
      

    Windows

    Mashup 不仅仅是发展的很快,更好的一个地方是你不再需通过某人才可以发布一个新API到网上。以前你必须要通过微软才可以发布一个新的API加入到Windows,这种情况同样出现在Macintosh。另,尽管你也许可以添加一个API直接到Linux,因为它是开源的,但是这对大多开发者来说并不具备这样的权利。
      另外,你在发布了一个API到网上之后,不需要再通过谁去批准它,它会自动对所有开发者有效。所有的不同的APIs都会成为更多Mashup的燃料。
      越来越多的Mashup出现在网上,越来越多的网络用户去使用这些新的Mashup应用程序。越来越多的开发者加入到开发Mashup这个生态系统当中。在未来两年,你将可以听到关于Mashup的信息。

    编辑本段典型应用

    地图 Mashup

      在这个阶段的信息技术中,人们搜集大量有关事物和行为的数据,二者都常常具有位置注释信息。所有这些包含位置数据的不同数据集均可利用地图通过令人惊奇的图形化方式呈现出来。mashup 蓬勃发展的一种主要动力就是 Google 公开了自己的 Google Maps API。这仿佛打开了一道大门,让 Web 开发人员(包括爱好者、修补程序开发人员和其他一些人)可以在地图中包含所有类型的数据(从原子弹灾难到波士顿的 CowParade 奶牛都可以)。为了不落于人后,Microsoft(Virtual Earth)、Yahoo(Yahoo Maps)和 AOL(MapQuest)也很快相继公开了自己的 API。

    视频和图象 Mashup

      图像主机和社交网络站点(例如 Flickr 使用自己的 API 来共享图像)的兴起导致出现了很多有趣的 mashup。由于内容提供者拥有与其保存的图像相关的元数据(例如谁拍的照片,照片的内容是什么,在何时何地拍摄的等等),mashup 的设计者可以将这些照片和其他与元数据相关的信息放到一起。例如,mashup 可以对歌曲或诗词进行分析,从而将相关照片拼接在一起,或者基于相同的照片元数据(标题、时间戳或其他元数据)显示社交网络图。另外一个例子可能以一个 Web 站点(例如 CNN 之类的新闻站点)作为输入,并在新闻中通过照片匹配而将照片中的内容以文字的形式呈现出来。

    搜索和购物 Mashup

      搜索和购物 mashup 在 mashup 这个术语出现之前就已经存在很长时间了。在 Web API 出现之前,有相当多的购物工具,例如 BizRate、PriceGrabber、MySimon 和 Google 的 Froogle,都使用了 B2B 技术或屏幕抓取的方式来累计相关的价格数据。为了促进 mashup 和其他有趣的 Web 应用程序的发展,诸如 eBay 和 Amazon 之类的消费网站已经为通过编程访问自己的内容而发布了自己的 API。

    新闻 Mashup

      新闻源(例如纽约时报、BBC 或路透社)已从 2002 年起使用 RSS 和 Atom 之类的联合技术来发布各个主题的新闻提要。以联合技术为基础的 mashup 可以聚集一名用户的提要,并将其通过 Web 呈现出来,创建个性化的报纸,从而满足读者独特的兴趣。

    微博 Mashup

      将多个微博在一个平台上进行聚合显示, 在一个平台上可以同时绑定多个微博(腾讯微博、新浪微博、搜狐微博、网易微博、人人网、豆瓣、饭否、嘀咕、Follow5、天涯微博、人间网、做啥、9911、同学网、开心网等),从而满足用户同步多个平台的要求,提供了微博信息汇总表,让用户方便查看自己所有平台的粉丝,关注和微博数,轻松实现在不同微博间自由切换。并且提供多微博评论列表读取,跨平台分享,聚合收藏等功能。使用户可在同一屏幕中同步收发信息,实现了真正意义上的社交网站双向聚合。类似网站功能的有玛撒网,微博通等。
    posted @ 2011-11-19 12:41 小马歌 阅读(258) | 评论 (0)编辑 收藏
     
    由 yangyi 于 2009-05-31 22:28:36 提供


    2009 年 5 月 25 日

    随着公开提供的 Web 服务 API 不断增加,现在可以轻松地从不同 Web 源获取资源并构建 mashup —— 只要您能访问正确的 API 和工具。探究如何能够结合高深的跨域调用技术(JSONP)和灵活的 JavaScript 库(jQuery),以快速构建强大的 mashup。

    简介

    Asynchronous JavaScript and XML (Ajax) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。

    不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?

    理解同源策略限制

    同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。

    克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。

    克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其他域中的服务 URL 并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供 Web 页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。幸运的是,通过添加 JavaScript Object Notation (JSON) 可以改进该技术。

    JSON 和 JSONP

    JSON 是用于在浏览器和服务器之间交换信息的轻量级数据格式(与 XML 相比)。JOSON 依赖于 JavaScript 开发人员,因为它是 JavaScript 对象的字符串表示。例如,假设有一个含两个属性的 ticker 对象:symbol 和 price。这是在 JavaScript 中定义 ticker 对象的方式:

    var ticker = {symbol: 'IBM', price: 91.42};

    并且这是它的 JSON 表示方式:

    {symbol: 'IBM', price: 91.42}

    从 参考资料 查找更多有关 JSON 和将其作为数据内部交换格式的信息。清单 1 定义了一个 JavaScript 函数,调用该函数时会显示 IBM 的股价。(我们没有详细介绍如何将该函数添加到 Web 页面)。


    清单 1. 定义 showPrice 函数
    function showPrice(data) {     alert("Symbol: " + data.symbol + ", Price: " + data.price); }                 

    可以将 JSON 数据作为参数传递,以调用该函数:

    showPrice({symbol: 'IBM', price: 91.42}); // alerts: Symbol: IBM, Price: 91.42                 

    现在准备将这两个步骤包含到 Web 页面,如清单 2 所示。


    清单 2. 在 Web 页面中包含 showPrice 函数和参数
    <script type="text/javascript"> function showPrice(data) {     alert("Symbol: " + data.symbol + ", Price: " + data.price); } </script> <script type="text/javascript">showPrice({symbol: 'IBM', price: 91.42});</script> 

    加载页面后,应该看如图 1 所示的警告。


    图 1. IBM ticker
    IBM ticker 

    至此,本文已展示了如何将静态 JSON 数据作为参数调用 JavaScript 函数。不过,通过在函数调用中动态包装 JSON 数据可以用动态数据调用函数,这是一种动态 JavaScript 插入的技术。要查看其效果,将下面一行放入名为 ticker.js 的独立 JavaScript 文件中。

    showPrice({symbol: 'IBM', price: 91.42});

    现在改变 Web 页面中的脚本,使其和清单 3 一样。


    清单 3. 动态 JavaScript 插入代码
    <script type="text/javascript"> // This is our function to be called with JSON data function showPrice(data) {     alert("Symbol: " + data.symbol + ", Price: " + data.price); } var url = “ticker.js”; // URL of the external script // this shows dynamic script insertion var script = document.createElement('script'); script.setAttribute('src', url);  // load the script document.getElementsByTagName('head')[0].appendChild(script);  </script> 				

    在清单 3 所示的例子中,动态插入的 JavaScript 代码位于 ticker.js 文件中,它将真正的 JSON 数据作为参数调用showPrice()函数。

    前面已经提到,同源策略不阻止将动态脚本元素插入文档中。也就是说,可以动态插入来自不同域的 JavaScript,并且这些域都携带 JSON 数据。这其实是真正的 JSONP(JSON with Padding):打包在函数调用中的 JSON 数据。注意,为了完成该操作,Web 页面必须在插入时具有已经定义好的回调函数,也就是我们例子中的 showPrice()

    不过,所谓的 JSONP 服务(或 Remote JSON Service)是一种带有附加功能的 Web 服务,该功能支持在特定于用户的函数调用中打包返回的 JSON 数据。这种方法依赖于接受回调函数名作为请求参数的远程服务。然后该服务生成对该函数的调用,将 JSON 数据作为参数传递,在到达客户端时将其插入 Web 页面并开始执行。





    回页首


    jQuery 的 JSONP 支持

    从 1.2 版本开始,jQuery 拥有对 JSONP 回调的本地支持。如果指定了 JSONP 回调,就可以加载位于另一个域的 JSON 数据,回调的语法为:url?callback=?

    jQuery 自动将 ? 替换为要调用的生成函数名。清单 4 显示了该代码。


    清单 4. 使用 JSONP 回调
    jQuery.getJSON(url+"&callback=?", function(data) {     alert("Symbol: " + data.symbol + ", Price: " + data.price); }); 

    为此,jQuery 将一个全局函数附加到插入脚本时需要调用的窗口对象。另外,jQuery 也能优化非跨域调用。如果向同一个域发出请求,jQuery 就将其转化为普通 Ajax 请求。

    使用 JSONP 支持的示例服务

    在上一个例子中,使用了静态文件(ticker.js)将 JavaScript 动态插入到 Web 页面中。尽管返回了 JSONP 回复,但它不允许您在 URL 中定义回调函数名。这不是 JSONP 服务。因此,如何才能将其转换为真正的 JSONP 服务呢?可使用的方法很多。这里我们将分别使用 PHP 和 Java 展示两个示例。

    首先,假设您的服务在所请求的 URL 中接受了一个名为 callback 的参数。(参数名不重要,但是客户和服务器必须都同意该名称)。另外假设向服务发送的请求是这样的:

    http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=showPrice

    在这种情况下,symbol 是表示请求 ticker symbol 的请求参数,而 callback 是 Web 应用程序的回调函数的名称。使用清单 5 所示的代码可以通过 jQuery 的 JSONP 支持调用该服务。


    清单 5. 调用回调服务
    jQuery.getJSON("http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=?",  function(data) {     alert("Symbol: " + data.symbol + ", Price: " + data.price); }); 

    注意,我们使用 ? 作为回调函数名,而非真实的函数名。因为 jQuery 会用生成的函数名替换 ?。所以您不用定义类似于showPrice() 的函数。

    清单 6 显示了用 PHP 实现的 JSONP 服务的一段代码。


    清单 6. 用 PHP 实现的 JSONP 服务的代码片段
    $jsonData = getDataAsJson($_GET['symbol']); echo $_GET['callback'] . '(' . $jsonData . ');'; // prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"}); 

    清单 7 显示了具有同样功能的 Java™ Servlet 方法。


    清单 7. 用 Java servlet 实现的 JSONP 服务
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp)    throws ServletException, IOException { 	String jsonData = getDataAsJson(req.getParameter("symbol")); 	String output = req.getParameter("callback") + "(" + jsonData + ");";  	resp.setContentType("text/javascript");            	PrintWriter out = resp.getWriter(); 	out.println(output); 	// prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"}); } 

    那么,如果要构建 mashup 应该怎么办,是从第三方服务器收集内容,并在单一的 Web 页面中显示它们吗?答案很简单:您必须使用第三方 JSONP 服务。这种服务并不少。

    现成的 JSONP 服务

    知道如何使用 JSONP 之后,可以开始使用一些现成的 JSONP Web 服务来构建应用程序和 mashup。下面为接下来的开发项目做准备。(提示:您可以复制特定的 URL 并将其粘贴到浏览器的地址栏,以检查生成的 JSONP 响应)。

    Digg API:来自 Digg 的头条新闻:

    http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript &callback=? 

    Geonames API:邮编的位置信息:

    http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?

    Flickr API:来自 Flickr 的最新猫图片:

    http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any &format=json&jsoncallback=?                 

    Yahoo Local Search API:在邮编为 10504 的地区搜索比萨:

    http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza &zip=10504&results=2&output=json&callback=? 





    回页首


    重要提示

    JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。

    JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。(参见 参考资料 了解更多信息)。





    回页首


    结束语

    在该系列的第一篇文章中,我们讲解了如何结合使用 JSONP 和 jQuery 快速构建强大的 mashup。主要主题包括:

    • 浏览器同源策略的限制以及解决办法
    • 作为一种有效的跨域通信技术,JSONP 能够绕过当前浏览器的同源策略限制
    • JSONP 使 Web 应用程序开发人员能够快速构建 mashup
    • 示例 JSONP 服务及其使用:Ticker 服务

    本系列的下一篇文章将介绍 Yahoo! 查询语言(YQL),这种单端点 JSONP 服务允许您跨 Web 查询、过滤和合并数据。最后还使用 YQL 和 jQuery 构建 mashup 应用程序。



    参考资料

    posted @ 2011-11-19 12:40 小马歌 阅读(264) | 评论 (0)编辑 收藏
     
    当不能预先确定报文体的长度时,不可能在头中包含Content-Length域来指明报文体长度,此时就需要通过Transfer-Encoding域来确定报文体长度。
        通常情况下,Transfer-Encoding域的值应当为chunked,表明采用chunked编码方式来进行报文体的传输。chunked编码是HTTP/1.1 RFC里定义的一种编码方式,因此所有的HTTP/1.1应用都应当支持此方式。
        chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下(BNF文法):
        Chunked-Body   = *chunk            //0至多个chunk
                         last-chunk         //最后一个chunk 
                         trailer            //尾部
                         CRLF               //结束标记符

       chunk          = chunk-size [ chunk-extension ] CRLF   
                            chunk-data CRLF
       chunk-size     = 1*HEX
       last-chunk     = 1*("0") [ chunk-extension ] CRLF

       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
       chunk-ext-name = token
       chunk-ext-val  = token | quoted-string
       chunk-data     = chunk-size(OCTET)
       trailer        = *(entity-header CRLF)      
        
        解释:
        Chunked-Body表示经过chunked编码后的报文体。报文体可以分为chunk, last-chunk,trailer和结束符四部分。chunk的数量在报文体中最少可以为0,无上限;每个chunk的长度是自指定的,即,起始的数据必然是16进制数字的字符串,代表后面chunk-data的长度(字节数)。这个16进制的字符串第一个字符如果是“0”,则表示chunk-size为0,该chunk为last-chunk,无chunk-data部分。可选的chunk-extension由通信双方自行确定,如果接收者不理解它的意义,可以忽略。
        trailer是附加的在尾部的额外头域,通常包含一些元数据(metadata, meta means "about information"),这些头域可以在解码后附加在现有头域之后。
        实例分析:
        下面分析用ethereal抓包使用Firefox与某网站通信的结果(从头域结束符后开始):
    Address  0..........................  f
    000c0                                31
    000d0    66 66 63 0d 0a ...............   // ASCII码:1ffc/r/n, chunk-data数据起始地址为000d5
             很明显,“1ffc”为第一个chunk的chunk-size,转换为int为8188.由于1ffc后马上就是
             CRLF,因此没有chunk-extension.chunk-data的起始地址为000d5, 计算可知下一块chunk的起始
             地址为000d5+1ffc + 2=020d3,如下:
    020d0    .. 0d 0a 31 66 66 63 0d 0a .... // ASCII码:/r/n1ffc/r/n
             前一个0d0a是上一个chunk的结束标记符,后一个0d0a则是chunk-size和chunk-data的分隔符。
             此块chunk的长度同样为8188, 依次类推,直到最后一块
    100e0                          0d 0a 31
    100f0    65 61 39 0d 0a......            //ASII码:/r/n/1ea9/r/n
             此块长度为0x1ea9 = 7849, 下一块起始为100f5 + 1ea9 + 2 = 11fa0,如下:
    100a0    30 0d 0a 0d 0a                  //ASCII码:0/r/n/r/n
             “0”说明当前chunk为last-chunk, 第一个0d 0a为chunk结束符。第二个0d0a说明没有trailer部分,整个Chunk-body结束。
        解码流程:
        对chunked编码进行解码的目的是将分块的chunk-data整合恢复成一块作为报文体,同时记录此块体的长度。
        RFC2616中附带的解码流程如下:(伪代码)
        length := 0         //长度计数器置0
        read chunk-size, chunk-extension (if any) and CRLF      //读取chunk-size, chunk-extension
                                                              //和CRLF
        while(chunk-size > 0 )   {            //表明不是last-chunk
              read chunk-data and CRLF            //读chunk-size大小的chunk-data,skip CRLF
              append chunk-data to entity-body     //将此块chunk-data追加到entity-body后
              read chunk-size and CRLF          //读取新chunk的chunk-size 和 CRLF
        }
        read entity-header      //entity-header的格式为name:valueCRLF,如果为空即只有CRLF
        while (entity-header not empty)   //即,不是只有CRLF的空行
        {
           append entity-header to existing header fields
           read entity-header
        }
        Content-Length:=length      //将整个解码流程结束后计算得到的新报文体length
                                     //作为Content-Length域的值写入报文中
        Remove "chunked" from Transfer-Encoding  //同时从Transfer-Encoding中域值去除chunked这个标记
        length最后的值实际为所有chunk的chunk-size之和,在上面的抓包实例中,一共有八块chunk-size为0x1ffc(8188)的chunk,剩下一块为0x1ea9(7849),加起来一共73353字节。
        注:对于上面例子中前几个chunk的大小都是8188,可能是因为:"1ffc" 4字节,"/r/n"2字节,加上块尾一个"/r/n"2字节一共8字节,因此一个chunk整体为8196,正好可能是发送端一次TCP发送的缓存大小。
     
    posted @ 2011-11-17 15:02 小马歌 阅读(474) | 评论 (0)编辑 收藏
     
    经测试,nginx +fpm,nginx无法探知 php输出内容长度,默认用Tranfer-Encoding:chunked编码 输出。

    对于一些客户端,需要自己解析http协议的,一般不支持chunked解码,这时,可以在php输出里 加一个header('Content-Length: length' ) 

    可以覆盖nginx的默认行为,计算内容长度可以用php自带的strlen 方法。
    posted @ 2011-11-17 14:59 小马歌 阅读(888) | 评论 (2)编辑 收藏
     
    RPM是Redhat Package Manage的缩写。透过RPM的管理,使用者可以把Source Code包装成一种Source和Binary的档案形式。利用它,我们可以用Binary的档案进行安装,用 Source 的档案形式重新整理包装。许多Linux爱好者对安装RPM包比较熟悉,但对如何在Linux下制作RPM包不甚了解,因此,我将通过实例,讲解如何在Linux下制作RPM包。 


    1. 最初要求 
    为了创建RPM,你需要RPM要编译的源代码、一个rpmrc文件(设置一些RPM的缺省值并控制它的行为),以及一个spec文件(控制包的建立过程)。这里假定已有其它的开发环境(gcc、make、install、vi等),而且你的源代码已经编译成功。 

    2. 制作流程 
    1)确定/etc/rpmrc(也可能是/usr/lib/rpm/rpmrc)已经正确设定。rpmrc文件控制几乎所有RPM的行为。如果你 想重载一个或多个全局设置,可以在~/.rpmrc文件中包含你的定制。可以使用rpm--showrc来显示RPM的当前设置。大多数情况下, rpmrc 文件的设置不需要改变。 

    2)取回所建造的源代码并放入正确的目录中。 

    3)编写spec文件。 

    4)使用rpm -ba 来构造整个程式套件。 

    3.应用举例 
    现在以Lynx实用程序来介绍构造RPM包的整个过程。Lynx是在文本方式下的Web浏览器,可以从ftp://www.slcc.edu/pub/lynx/取得。 

    1)得到lynx源代码。 

    2)lynx-2.8.spec文件的详细编写方法略。 

    3)使用RPM来构造包。 

    按照rpmrc文件的缺省设置,应该把lynx-2.8.spec文件放入SPECS/目录下,然后执行: 

    rpm -ba lynx-2.8.spec 

    其中-b 表示prep、compile、install,并build出一份binary RPM包。-a 表示执行所有的build动作,即还要build 出一份source code RPM包。 

    如果一切顺利的话,可以在RPMS/目录下找到lynx-2.8-4.i386.rpm文件。可以执行: 

    rpm -qpl lynx-2.8-4.i386.rpm 

    来观察RPM 包中是否包含了要求的所有文件。 

    为了测试它的正确性,可以拷贝此文件到另一台机器上,并执行: 

    rpm -ivh lynx-2.8-4.i386.rpm 

    进行安装测试。 

    一旦测试成功,就可以上载你的大作,享受成功的喜悦。 

    小结 

         制作RPM包需要开发人员做很多工作。比如不仅要懂得c/c++编程,而且还要能熟练掌握像make、autoconf、diff、 patch、tar、install等工具的使用并能编写spec文件。但从长远来看,应用RPM,在软件包的维护和方便性方面使得开发者受益。

    原文:http://www.host01.com/article/server/00070002/0542417260388231.htm
    posted @ 2011-11-15 14:51 小马歌 阅读(158) | 评论 (0)编辑 收藏
     

    最近公司要开发新的产品,在本地搭建了一下服务端的开发环境,安装centos5.5,安装了一些编译php需要的库文件gd,libxml,zlib等等,n多操作后,再使用yum时发现如下错误:

    [root@home ~]# yum update
    Setting up Update Process
    Setting up repositories
    Segmentation fault

     

    [root@home ~]# strace yum update

    last lines of strace :

    _llseek(6, 0, [0], SEEK_CUR) = 0
    read(6, "<?xml version=\"1.0\" ?><repomd xm"..., 8192) = 3846
    read(6, "", 4346) = 0
    --- SIGSEGV (Segmentation fault) @ 0 (0) ---
    +++ killed by SIGSEGV +++

     

    google大神和百度大神了n次,基本都是一样的解决方案(1、yum clean all 2、修改源 3、修改yum.conf),照此执行,但并不能解决我的问题,有点绝望,但上天不负有心人,找到了这个 http://bugs.centos.org/view.php?id=4702&nbn=1

    给了我们(我和我的同事)一些启发,原来是我们安装的zlib1.2.5时指定了安装目录(./configure -prefix=/usr)对yum产生了影响,所以总结如下:

    1、安装完系统后,运行一次#yum update(yum产生了缓存) ,然后再安装zlib1.2.5,之后如果不执行#yum clean all,则一直可以使用yum,不会报段错误

    2、如果在执行yum前已经安装了zlib1.2.5,则需要做如下处理

    #cd /usr/lib

    #ln -sf libz.so.1.2.3 libz.so

    #ln -sf libz.so.1.2.3 libz.so.1

    但此后zlib就使用了旧版本,在成功执行了yum后,还需要将软连接更改

    #cd /usr/lib

    #ln -sf libz.so.1.2.5 libz.so

    #ln -sf libz.so.1.2.5 libz.so.1

    至此,问题解决了!

    posted @ 2011-11-15 14:08 小马歌 阅读(1037) | 评论 (0)编辑 收藏
     

    以前在Debian下安装软件都是使用软件源安装的,虽然步骤较少,但仍不能理解Linux下安装软件的具体细节,于是决定手动编译安装各种软件,以解心中困惑
    由于国内租用虚拟主机或VPS 价格都较高,而虚拟主机虽价格适中,但不利于学习各种系统,综上考虑还是从网上购买国外VPS,试用了几天,测试效果还是比较满意. 在使用时没有写下编译安装Nginx-1.0.5 + MySQL-5.5.15 +PHP-5.3.8,现在决定写下此过程,以供今后参考。

    由于提供的VPS系统中没有Debian 6.0 ,只能选择使用5.0或4.0的版本,没法只好安装5.0的Debian,以下为安装步骤。

    首先下载本文要用到的相关软件:

    下载在Linux公社的1号FTP服务器里,下载地址:

    FTP地址:ftp://www.linuxidc.com

    用户名:www.linuxidc.com

    密码:www.muu.cc

    在 2011年LinuxIDC.com\9月\Debian下Nginx-1.0.5 + MySQL-5.5.15 +PHP-5.3.8编译安装相关文件

    下载方法见 http://www.linuxidc.net/thread-1187-1-1.html

    一. 检查系统环境

    1. netstat -ntlp 查看系统中运行哪些网络服务,不需要用的都可以关掉,比如exim4(邮件服务程序), aptitude purge exim4-base exim4-config exim4-daemon-light .

    2. 安装编译环境,debian 5系统发行版默认没有安装gcc等工具。需安装一下

    aptitude install build-essential

    二. 编译安装相关组件

    1.安装zlib,openssl等组件


    unzip -x zlib125.zip
    cd zlib-1.2.5
    ./configure --prefix=/usr
    make && make install

    tar zxvf openssl-0.9.8r.tar.gz
    cd openssl-0.9.8r
    make && make install

    2.安装 nginx
    tar zxvf pcre-8.13.tar.gz
    tar zxvf nginx-1.0.5.tar.gz
    cd nginx-1.0.5
    ./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin --with-http_ssl_module --with-http_sub_module --with-http_flv_module --with-http_stub_status_module --with-zlib=../zlib-1.2.5 --with-openssl=../openssl-0.9.8r --with-pcre=../pcre-8.13make && make install

    配置开机启动

    cp nginx.txt /etc/init.d/nginx
    chmod + x /etc/init.d/nginx
    chkconfig nginx on
        
    3.安装 mysql ,安装mysql-5.5.15需安装cmake ,
    tar zxvf cmake-2.8.5.tar.gz
    cd cmake-2.8.5
    ./bootstrap
    make
    make install 
    在安装最后一步时可能会出错,解决办法是指定安装位置make install DESTDIR=/usr/local.

    建立mysql安装目录及数据目录
    mkdir -p /usr/local/mysql
    mkdir -p /data/mysql

    建立mysql用户及组
    groupadd mysql
    useradd -d /usr/local/mysql -g mysql -s /usr/sbin/nologin mysql

    设定目录mysql目录属主及权限
    chown mysql.mysql /usr/local/mysql
    chown -R mysql.mysql /data/mysql
    chmod 755 /usr/local/mysql
    chmod -R 755 /data/mysql

    用cmake编译安装mysql
    cd mysql-5.5.15
    cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
    -DMYSQL_DATADIR=/data/mysql/ \
    -DWITH_INNOBASE_STORAGE_ENGINE=1 \
    -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
    -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
    -DWITH_FEDERATED_STORAGE_ENGINE=1 \
    -DWITH_PARTITION_STORAGE_ENGINE=1 \
    -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \
    -DMYSQL_TCP_PORT=3306 \
    -DENABLED_LOCAL_INFILE=1 \
    -DEXTRA_CHARSETS=all \
    -DDEFAULT_CHARSET=utf8 \
    -DDEFAULT_COLLATION=utf8_general_ci \
    -DMYSQL_USER=mysql
    编译过程中可能会出错,需安装libncurses5-dev及bison
    aptitude install libncurses5-dev bison
    然后删除CMakeCache.txt
    rm CMakeCache.txt
    继续编译通过
    make
    make install

    复制配置文件my.cnf
    cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf
    chown mysql.mysql /etc/my.cnf
    chmod 755 /etc/my.cnf

    配置开机启动
    cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    chmod +x /etc/init.d/mysqld
    chkconfig mysqld on

    启动mysql并设置密码
    /etc/init.d/mysqld start
    /usr/local/mysql/bin/mysqladmin -u root password '新密码'

    OK,mysql配置完成。

    4.安装php
    编译gd库,这个在搭建discuz论坛时需用到

    (1)安装libpng

    tar zxvf libpng-1.5.4.tar.gz
    cd libpng-1.5.4
    ./configure
    make 
    make install

    备注: libpng默认安装位置/usr/local,若指定安装在/usr/local/png,则编译gd时会提示找不到png.h等文件.

    (2)安装freetype

    tar zxvf freetype-2.4.6.tar.gz
    cd freetype-2.4.6
    ./configure --prefix=/usr/local/freetype
    make
    make install

    (3)安装jpeg

    tar zxvf jpegsrc.v8c-tar.gz
    cd jpeg-8c
    ./configure --prefix=/usr/local/jpeg
    make
    make install

    (4) 安装libxml2

    tar zxvf libxml2-2.7.8.tar.gz
    cd libxml2-2.7.8
    ./configure --prefix=/usr/local/libxml2
    make
    make install

    (5)安装GD

    tar zxvf pierrejoye-gd-libgd-GD_2_0_33.tar.gz
    cd pierrejoye-gd-libgd-GD_2_0_33
    ./configure --prefix=/usr/local/gd --with-png=/usr/local --with-freetype=/usr/local/freetype --with-jpeg=/usr/local/jpeg
    make
    make install

    (6)编译PHP

    ./configure \
    --prefix=/usr/local/new_php \
    --with-config-file-path=/usr/local/new_php/etc \
    --enable-fpm \
    --with-fpm-user=nobody \
    --with-fpm-group=nobody \
    --with-libxml-dir \
    --with-openssl \
    --with-zlib \
    --with-gd \
    --with-jpeg-dir \
    --with-png-dir \
    --with-freetype-dir \
    --enable-gd-native-ttf \
    --enable-gd-jis-conv \
    --with-mhash \
    --enable-mbstring \
    --with-mcrypt \
    --with-mysql \
    --with-mysql-sock=/tmp/mysqld.sock \
    --with-mysqli=/usr/bin/mysql_config \
    --enable-sockets \
    --enable-sysvmsg \
    --enable-sysvsem \
    --enable-sysvshm


    make
    make test
    make install

    复制php.ini到配置文件目录及php-fpm 开机启动
    cp php.ini-production /usr/local/php/etc/php.ini
    cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
    chmod +x /etc/init.d/php-fpm
    这时候还不能使用/etc/init.d/php-fpm start启动,需修改一下php-fpm配置文件才可以,配置文件位置php安装目录 etc 目录下,默认有个参考文件.
    cp php-fpm.conf.default php-fpm.conf
    nano php-fpm.conf
    ,pm.start_servers = 20
    ,pm.min_spare_servers = 5
    ,pm.max_spare_servers = 35
    去掉以上三项前面的逗号,这时再使用/etc/init.d/php-fpm start 即可启动。
    Memcahed构建与安装php memcache

    1.memcached需用到libevent这个库

    tar zxvf libevent-2.0.12-stable.tar.gz
    cd libevent-2.0.12-stable
    ./confiugre --prefix=/usr
    make && make install

    2.安装memcached

    tar zxvf memcached-1.4.6.tar.gz
    cd memcached-1.4.6
    ./configure --with-libevent=/usr
    make && make install
    在make install这步时出错了,竟不能安装,查看了错误原因,原来是/usr/local/man目录中已存在一个man1,于是改名man2,再次make install成功.

    3.安装 php memcache扩展

    tar xvf memcache-3.0.6.tgz
    cd memcache-3.0.6
    /usr/local/php/bin/phpize
    ./configure --enable-memcache --with-php-conf=/usr/local/php/bin/php-config --with-zlib-dir=/usr
    make
    make test
    make install
    安装完成后,提示
    Installing shared extensions:  /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626

    配置php.ini文件
    在文件最后添加
    extension_dir="/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626"
    extension=memcache.so


    查看php是否成功加载memcache.so
    /usr/local/php/bin/php -m


    [PHP Modules]
    Core
    ctype
    date
    dom
    ereg
    fileinfo
    filter
    gd
    hash
    iconv
    json
    libxml
    mbstring
    mcrypt
    memcache
    mhash
    mysql
    mysqli
    openssl
    pcre
    PDO
    pdo_sqlite
    Phar
    posix
    Reflection
    session
    SimpleXML
    sockets
    SPL
    SQLite
    sqlite3
    standard
    sysvmsg
    sysvsem
    sysvshm
    tokenizer
    xml
    xmlreader
    xmlwriter
    zlib


    [Zend Modules]

    在15行看到了memcache,已成功加载

    启动memcached服务端程序
    memcached -d -m 64 -u www-data -l localhost -p 11211 -c 640 -P /tmp/Memcached.pid

    各个参数的意义
    -d选项是启动一个守护进程,
    -m是分配给Memcached使用的内存数量,单位是MB,
    -u是运行Memcache的用户,我这里是root,
    -l是监听的服务器IP地址,
    -p是设置Memcache监听的端口,最好是1024以上的端口,
    -c选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定,
    -P是设置保存Memcache的pid文件

    配置memcached开机启动

    cp memcached.txt /etc/init.d/memcached
    chmod + x /etc/init.d/memcached
    chkconfig memcached on





    posted @ 2011-11-15 14:02 小马歌 阅读(648) | 评论 (0)编辑 收藏
     

    一、Nginx安装
    安装的时候需要注意加上 –with-http_ssl_module,因为http_ssl_module不属于Nginx的基本模块。
    Nginx安装方法:

    ./configure –user=username –group=groupname –prefix=/usr/local/nginx –with-http_stub_status_module –with-http_ssl_module
    make && make install

    二、生成证书(略)
    可以使用openssl或ca.ssl生成,结果生成如下两个文件:

    server.crt
    server.key

    如果是apache,直接将这两个文件引入到httpd.conf中,而Nginx需要的是.pem文件。.pem的生成方法很简单,就是合并server.crt、server.key的内容。

    三、修改Nginx配置:

    server
    {
    listen 443;
    server_name test.sina.com.cn;
    ssl on;
    ssl_certificate /tmp/server.pem;
    ssl_certificate_key /tmp/server.key;
    ssl_session_timeout 5m;
    ssl_protocols SSLv2 SSLv3 TLSv1;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
    }

    posted @ 2011-11-15 11:28 小马歌 阅读(434) | 评论 (0)编辑 收藏
    仅列出标题
    共95页: First 上一页 46 47 48 49 50 51 52 53 54 下一页 Last