2013/10/16

HTTP compression for Jetty

HTTP compression可以將web server在將資料傳回browser前,先進行壓縮;browser收到壓縮後的資料後,先做解壓縮後再呈現出來。這好處是可以減少傳遞的資料量,讓網路的傳輸速度加快,而缺點則是要耗用兩端的CPU資源來進行壓縮。

當然,web server並不是隨意進行壓縮,必須視browser有支援何種解壓縮功能,才用合適的壓縮方法進行壓縮。一般browser在送出request時:
GET /the-page HTTP/1.1
Host: www.the-web-site.com
Accept-Encoding: gzip, deflate


在Accept-Encoding這個header parameter中,就描述了browser可以處理的解壓縮方法。Web server則會視雙方都有支援的壓縮方法來進行壓縮。

目前市面上的browsers與web servers多已經支援HTTP compression的功能(HTTP compression測試工具)。一般web server並未開啟compression的功能,這裡以 Jetty 8/9來說明如何開啟這項功能。

首先找到web.xml,然後加入下列這段code:
  <filter></filter>
      <filter-name>GzipFilter</filter-name>
      <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
      <init-param></init-param>
          <param-name>mimeTypes</param-name>
          <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,application/x-javascript,application/json,image/svg+xml</param-value>
     
  <filter-mapping></filter-mapping>
      <filter-name>GzipFilter</filter-name>
      <url-pattern>/*</url-pattern>


這段設定是使用Jetty中所附的GzipFilter,可支援gzip與deflate的壓縮。
在init-param中定義了有那些MIME types是需要被壓縮的。一般而言,圖片、音樂(mp3...)、PDF等等都已經是經過壓縮的,所以並不建議再列入。
而在 url-pattern中則是定義了那個目錄要被壓縮,這裡設定整個網站目錄都列入範圍。

那要怎麼知道傳回來的是不是壓縮的格式。
可以打開browser的開發者工具,看看response headers的Content-Encoding是否為gzip等的壓縮方式。

後記:個人的測試,在Jetty 8上,好像request method只能用GET,如果用POST,則回傳資料不會壓縮。在一些文件中並沒有看到說POST的response不會壓縮。就不知是Jetty的因素?還是規格有這樣的限制了。等有空時再來研究這問題了。

2013/09/28

藍天,逐漸地被叢起的大樓切割竊佔

國美館,每個角落都值得細細品味

2013/09/06

在IE中遇到innerHTML的錯誤

工作紀錄

在寫AJAX式的網頁程式時,常會使用innerHTML來置換掉某部份內容。例如:
document.getElementById("someid").innerHTML = "xxxxxx";

今天遇到一個問題,在HTML中有
    <div id="mydiv">
        <table id="mytable" style="width: 99%px;"></table>
    </div>

然後用下列的JavaScript來填入table的內容:
      var s = "<tr><td>AAA</td><td>BBB</td></tr>";
      document.getElementById("mytable").innerHTML = s;

這樣的方式在Firefox, Chrome, Opera等都正常,唯獨 IE (8 & 9) 有問題,會出現"未知的執行階段錯誤" (unknown runtime error) 或 SCRIPT600 error。

後來發現,必須要用下列的方式才能滿足這四種browsers。
      var s = "<table id="mytable" style="width: 99%px;"><tr><td>AAA</td><td>BBB</td></tr></table>";
      document.getElementById("mydiv").innerHTML = s;
 
猜測:IE在填值到innerHTML時,可能會檢查所填入的內容。前面的例子只填入table的內容,沒有包含<table></table>的tag,IE可能認為這是不完整的內容而發生錯誤。後者則因包含了<table></table>tag,是完整的語法,因此就能接受。

後來也試了<select> tag,如果只給innerHTML一堆<option> tags,也是會有這樣的錯誤,若是包含select tag就OK了。

呼叫SVG裡的javascript method

工作筆記

A.html中用下面的tag包含了一個SVG

在B.svg中有一個JavaScript function: myfunction()

如果要從A.html呼叫B.svg裡的這個function,可以用下面的方法來進行
document.getElementById("svg").getSVGDocument().defaultView.myfunction();