2007年11月14日

JSONP

The script tag method for cross-domain data fetching: JSON with Padding, or simply JSONP. - Bob Ippolito

緣由

為了安全,瀏覽器中的javascript不能存取位在不同domain的資料,這稱做same-origin policySame-Origin Policy Part 1: Why we’re stuck with things like XSS and XSRF/CSRF中說的很清楚:

Put simply, same-origin prevents a document or script loaded from one site of origin from manipulating properties of or communicating with a document loaded from another site of origin. In this case the term origin refers to the domain name, port, and protocol of the site hosting the document. The following list covers the major actions that cause the browser to check access against the same-origin policy:
  • manipulating browser windows
  • URLs requested via the XmlHttpRequest
  • manipulating frames (including inline frames)
  • manipulating documents (included using the object tag)
  • manipulating cookie

但是HTML本身仍可以加入很多其他domain的資源。

The above restrictions don’t limit all interaction, however. There is no limitation on including documents from other sources in HTML tag elements. It’s fairly common for images, style sheets, and scripts to be included from other domains. In fact, the only time same-origin explicitly restricts document retrieval is when the XmlHttpRequest method is used.

若是需要cross domain取得資料時,例如使用其他網站提供的web service,就需要一些額外的輔助,例如local proxy,但是一般的使用者,無法在server上放proxy。 於是Bob Ippolito提出了以下的建議:

  • 使用script tag載入javascript檔的方式,可以cross domain取得資料。
  • server端傳回的資料採JSON(Javascript object notation)格式。
  • server端提供一項服務,接受回呼函式(callback function)名稱為參數,將傳回的資料當成回呼函式的參數,傳回對此回呼函式的呼叫(padding 所指的就是此加上回呼函式的填充動作)。當此javascript傳輸完成,client端會自動執行,呼叫此回呼函式,因此在資料傳輸完畢時可以得知。

這裡需要的是server端的幫助,目前GoogleYahoo等的服務都有提供JSONP格式的回傳。

範例

Flickr提供的服務查詢標籤包含羅平、油菜花、sunset的公開照片,並加入參數format=json、jsoncallback=doPhoto,表示傳回資料為JSON格式,並將其填入回呼函式doPhoto的呼叫中作為參數:

<script type="text/javascript" src="http://api.flickr.com/services/feeds/photos_public.gne?tags=羅平,油菜花,sunset&tagmode=all&format=json&jsoncallback=doPhoto">

會得到「回呼函式名稱(JSON格式資料)」這種格式的回傳:

doPhoto({
"title": "每個人的相片 已標籤 羅平, 油菜花 和 sunset",
"link": "http://www.flickr.com/photos/",
"description": "",
"modified": "2007-04-22T14:19:09Z",
"generator": "http://www.flickr.com/",
"items": [
{
"title": "羅平金雞嶺夕陽",
"link": "http://www.flickr.com/photos/38362352@N00/468370409/",
"media": {"m":"http://farm1.static.flickr.com/211/468370409_319f383a24_m.jpg"},
"date_taken": "2007-04-22T22:19:09-08:00",
"description": "...",
"published": "2007-04-22T14:19:09Z",
"author": "nobody@flickr.com (Nature RGB)",
"author_id": "38362352@N00",
"tags": "sunset yunnan 油菜花 羅平"
}
]
})

當回傳載入完畢後,client端執行上面這段javascript,便會呼叫之前定義好的doPhoto,這裡做的是秀出查詢的圖片(請原諒我憋腳的javascript):

function doPhoto(result) {
var div = document.getElementById("flickr photos");
for(var i=0; i < result.items.length; i++) {
var img = document.createElement("img");
img.setAttribute("src",result.items[i].media.m);
img.setAttribute("alt",result.items[i].title);
var a = document.createElement("a");
a.setAttribute("href",result.items[i].link);
a.setAttribute("target","_blank");
a.appendChild(img);
div.appendChild(a);
}
}
Read more

2007年11月9日

Syntax Highlight

厭倦了單調的程式碼嗎,來加點色彩吧!

當你需要某種軟體功能時,要花多久時間才能找到讓你滿意的答案呢?龐大的資料量,加上不同的用語、語言、資料來源,使得需要在搜尋結果中花費很多時間來篩選,然後還要再一一測試,而且說不定還找不到想要的結果。所以搜尋引擎還有很多進步空間,suryvey、catalog類型的網站或文章還是需要的。

對於將程式碼加上語法色彩,大致上分為兩類,事先產生後將靜態的資料貼到網頁上,或是以javascript線上即時修改網頁,以下是一些例子:

事先產生:

1. Highlight(名字真直接)
桌上軟體,可將檔案轉換成所選的格式,語法以副檔名判斷,可選擇配色、CSS是否inline、是否顯示行數,可自行定義語法及配色,若輸出格式選擇UTF-8,中文在預覽視窗會是亂碼,不過輸出的結果是正確的。

Highlight Screen Capture
因為使用CSS檔,以下程式碼在feeds中顯示會有問題。
//syntax highligth 測試程式碼
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  logger.info("copy 開始!");
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
  logger.info("copy 結束!");
}

2. SyntaxColor4Writer (Windows Live Writer Plugin)
需要.NET 2.0,使用inline CSS,神奇的是會將WLW轉換編輯模式後吃掉的空白和斷行回復。
註:0.26版在WLW 12.0.1367.1128無法執行

//syntax highligth 測試程式碼
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  logger.info("copy 開始!");
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
  logger.info("copy 結束!");
}

3. CodeSnippet(Eclipse plugin)
將所選程式片段依Editor中的顏色設定產生輸出,因為如此所以不需要定義語法,但是目前只支援幾種格式,使用inline CSS。

//syntax highligth 測試程式碼
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  logger.info("copy 開始!");
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
  logger.info("copy 結束!");
}

4. Iris Syntax Highlighter(C# Open Source)
提供網頁版syntax highlight介面,下載版需要.NET 2.0,利用Vim(一種文字編輯器)已有的語法定義檔,支援超過460種語法,可選擇配色、是否顯示行數,可自行定義語法及配色。

//syntax highligth 測試程式碼
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  logger.info("copy 開始!");
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
  logger.info("copy 結束!");
}
1
2
3
4
5
6
7
8

線上即時:

1. SyntaxHighlighter (Yahoo Developer Network上有在用)
可以處理<textarea>(ps. 為了在feed中有較好的顯示結果,最好還是使用<pre>),使用CSS檔做樣式,適合用在少量程式碼的情況(因為用regular expression來做parse),在Blogger上因為轉換換行符號的問題,需要特別設定(只是多呼叫一個函示)。

//syntax highligth 測試程式碼
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
logger.info("copy 開始!");
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
logger.info("copy 結束!");
}
Read more

2007年11月7日

Blog Editor

編輯blog文章,這麼常做的事反而這麼不方便。

Weblog的出現以及網路環境的成熟,讓個人發表網頁變的簡單了,blog的數量一下子增加,這麼多人每天進行的活動,照理說應該存在適當的輔助工具,但是卻沒有。(或是有但我沒找到)

目前我是先在客戶端以自己喜歡的網頁編輯器編輯好文章,用瀏覽器測試自己想要的效果,然後登錄到Blogger的線上介面,貼上文章的HTML。

使用Blogger線上編輯器有些需要注意的事:
  • 要在「設定」>「格式」頁面中將選項「轉換分行符號」設定為,否則在線上編輯器中的換行會被換成<br />。
    (通常在編輯HTML時都不會把所有內容排成一行,如果不改設定就會出現一大堆換行)
  • 不要按到網頁編輯器中的撰寫(其實就是所視即所得的編輯方式),不然一些自動轉換會改變你的文章格式。
    (例如<pre></pre>中的空白和換行會被壓縮成一個空白)
  • 預覽看到的是將轉換分行符號設定為是的結果。

這種土法煉鋼的方式其實是很不方便的,這時如果有一個好用的離線部落格編輯器就好了,最好要是免錢的!(少男的祈禱~~)
但是…現實總是殘酷的!
參考了Top 10 Free Desktop Blog Editors for Windows十大免費部落格寫作軟體之旅中的幾個比較可以行的軟體,只考慮編輯、上下載文章這兩種最基本的功能:

  • Windows Live Writer beta 3
    編輯:切換編輯模式會修改網頁(空白和換行會被壓縮成一個空白、HTML保留符號會被自動轉換,對於有貼程式碼的會造成困擾)
    上下載:會修改網頁(空白和換行會被壓縮成一個空白、HTML保留符號會被自動轉換)、下載文章會失敗
  • Zoundry Blog Writer 1.0.40
    編輯:切換編輯模式會修改網頁(HTML保留符號會被自動轉換)
    上下載:會修改網頁格式(HTML保留符號會被自動轉換、為了只顯示文章摘要所加的<div id="fullpost"></div>不見了)
  • Zoundry Raven alpha 0.8.134
    編輯:下載文章失敗就不太想測了,不過看起來好像還ok
    上下載:下載文章會失敗(好像是XML not well-formated)
  • Flock 1.0
    編輯:切換編輯模式會修改網頁(空白和換行會被壓縮成一個空白、HTML保留符號會被自動轉換)
    上下載:沒有下載功能
  • ScribeFire 1.4.2 (Mozilla Firefox 附加元件)
    編輯:切換編輯模式會修改網頁(空白和換行會被壓縮成一個空白、HTML保留符號會被自動轉換)
    上下載:顯示上載成功,但實際上卻沒有上載

當然光批評比實際上去做要容易的多,而且這些是免費的軟體,很多都還在測試階段,有很多問題感覺好像都是自動轉換格式造成的,而且似乎只會對想貼程式碼,或不想網頁元素變成一坨的人有影響,難怪還是有人覺得好用。
所以…向流星許願吧!希望好用的blog editor早日出現。

Read more

2007年11月4日

Code Snippet

想要在blog貼一段程式碼,這是個很基本的需求,但是真麻煩。

假設想要貼上以下這段java程式碼:

public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
}

首先會遇到兩個問題,「<」、「>」在HTML用來表示標籤,必須要用「&lt;」取代「<」,「&gt;」取代「>」,否則無法正常顯示,還有一些特殊用途的符號也需要避開:「&amp;」取代「&」,「&quot;」取代「"」,另外就是空白和斷行的問題,必須要用「&nbsp;」(non-breaking space)和「<br />」表示(r和/之間的空格好像是為了相容於較舊的瀏覽器),不過若是使用網頁編輯器,通常都會自動置換這些符號。
程式碼片段可以放在<code></code>之間,但是這個標籤只是用來增加文字片段的結構資訊,對於頁面的顯示沒有影響。
接著通常會以CSS來修改顯示方式,這時就看個人的創意了,例如:

/* for code */
code, .code {
  display: block;
  background: #E3F5D2;
  padding: 10px 10px 10px 21px;
  margin: 10px;
  border: 1px solid #CCCCCC;
  max-height: 300px;
  overflow: auto;
  font-family: "Courier New", Courier, monospace;
  font-size: 95%;
  line-height: 120%;
}

<code> example:

//This is a code tag test
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
}
<code>
<span style="color:#FF0000">//This is a code tag test</span><br />
public static &lt;T&gt; void copy(List&lt;? super T&gt; dst, List&lt;? extends T&gt; src) {<br />
&nbsp;&nbsp;for (int i = 0; i &lt; src.size(); i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;dst.set(i, src.get(i));<br />
&nbsp;&nbsp;}<br />
}
</code>

但以這種方法來處理空白和斷行,還是太麻煩了,這時可以試試看「<pre>」或「<textarea>」。
<pre></pre>(preformatted text)會將標籤所包圍的空白和斷行顯示在網頁上,但仍舊會處理其中的HTML標籤,所以仍需要置換特殊符號,這也表示可以用CSS修飾程式碼。
<textarea></textarea>會將標籤所包圍的文字全部顯示,但這也表示無法用CSS修飾程式碼,而且比較麻煩的是必須自己設定寬高和唯讀等屬性。(這是目前所知的情況,也許有其他的好方法可以辦到。)

<pre> example:

//This is a pre tag test
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
  for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
  }
}
<pre class="code">
<span style="color:#FF0000">//This is a pre tag test</span>
public static &lt;T&gt; void copy(List&lt;? super T&gt; dst, List&lt;? extends T&gt; src) {
for (int i = 0; i &lt; src.size(); i++) {
dst.set(i, src.get(i));
}
}
</pre>

<textarea> example:

<textarea name="textarea" rows="6" readonly="readonly" class="code" style="width:90%">
//This is a textarea tag test
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
</textarea>

所以結論是,用<pre>似乎是比較方便的方法,不用自己設定寬高,也可以用CSS修飾達成syntax highlight的效果。

Read more