2009年10月28日星期三

ASP.NET Server Side & Client Side資料加密處理

來自 亞特蘭提斯 著
對於ASPX網頁上暫存資料方面,ServerSide最常用多數都是用Session,ClientSide應該都是ViewState吧,前者應該沒有太多保安問題,但後者的ViewState其實要Decode根本不難,所以加密功夫其實很重要的。近期工作上經常要使用 jQuery + Web Service處理資料,有些敏感資料會經JSON傳回Browser,又或者經Hidden Field傳回Server,有些情況是很難避免的 (特別是上司要求…),我看過有些懶人只用Base64轉碼就當是加密其實真的很危險。

.NET Framework其實本身在System.Security.Cryptography NameSpace下已經提供了大量加密方式,在MSDN看過後,取了幾種針對String加密的,做了少少資料搜集有關 3DES / DES / RSA 和 AES (Rijndael) 的比較,其實4種方法同樣都需要一項Key才可以進行正常解密,所以即使知道你網頁中加密後的字串,而不知道你所設定的Key都不可能正常解密的。

論安全性,粗略評估後的排行應該是 AES (Rijndael) > AES > 3DES > RSA / DES。

至於使用方面,Client-Side可以使用以下的Javascript 解密AES:
http://www.movable-type.co.uk/scripts/aes.html

Server-Side方面,其實MSDN上已有很清晰的Sample,以下就是使用AES (Rijndael)方式對String進行encrypt和decrypt的例子。

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class RijndaelSample
{

static void Main()
{
try
{
// Create a new Rijndael object to generate a key
// and initialization vector (IV).
Rijndael RijndaelAlg = Rijndael.Create();

// Create a string to encrypt.
string sData = "Here is some data to encrypt.";
string FileName = "CText.txt";

// Encrypt text to a file using the file name, key, and IV.
EncryptTextToFile(sData, FileName, RijndaelAlg.Key, RijndaelAlg.IV);

// Decrypt the text from a file using the file name, key, and IV.
string Final = DecryptTextFromFile(FileName, RijndaelAlg.Key, RijndaelAlg.IV);

// Display the decrypted string to the console.
Console.WriteLine(Final);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

Console.ReadLine();
}

public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);

// Create a new Rijndael object.
Rijndael RijndaelAlg = Rijndael.Create();

// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateEncryptor(Key, IV), CryptoStreamMode.Write);

// Create a StreamWriter using the CryptoStream.
StreamWriter sWriter = new StreamWriter(cStream);

try
{
// Write the data to the stream
// to encrypt it.
sWriter.WriteLine(Data);
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sWriter.Close();
cStream.Close();
fStream.Close();
}
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
}

}

public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);

// Create a new Rijndael object.
Rijndael RijndaelAlg = Rijndael.Create();

// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream, RijndaelAlg.CreateDecryptor(Key, IV), CryptoStreamMode.Read);

// Create a StreamReader using the CryptoStream.
StreamReader sReader = new StreamReader(cStream);

string val = null;

try
{
// Read the data from the stream
// to decrypt it.
val = sReader.ReadLine();

}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sReader.Close();
cStream.Close();
fStream.Close();
}

// Return the string.
return val;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
}
}

2009年10月14日星期三

Project Manager 唔識 Program (轉載)

起香港做電腦行業,要上位做到Manager級,
大概可以分三類,1.高相關學歷 2.真材實料 3.靠吹水 。
第1.和第2. 是無可厚非的,至於第3.認唔認同就因人而異,個人就唔太認同。

在Google上輸入Keyword : Project Manager 唔識 Program ,已經可以找到相關討論:
香港討論區 » 各行各業 » 資訊科技界 I.T. »
唔識寫code的manager有X用咩
Coding 係 IT行業吾係想像中重要
唔識寫code就咪學人做manager啦
唔識寫code的manager/官員, 就係禍港之根本

PM需唔需要識Programming? 我覺得絕對要識,但需唔需要超強?咁又未必。當然如果Coding 都強的話當然就更加好喇,我諗任何人都唔想有事時,PM十問九唔知,話知但又唔肯定的。

Project Manager – 職責就是Project Management : Resource Control / Documentation / Source Control 等等之外,就連Database Design都要。
以近期我做的Project Database做例,就說明現實中PM要不要懂Programming。



這個Table有幾點都有問題 :
1. ParentMenuCode和Code,實際data是INT,但DataType卻有理冇理Set Nvarchar….
2. ParentMenuCode是FK Reference Code,實質就是主Menu和副Menu的關係,但理應分開兩個Table,現在放在一起,就會出現recursive的情況,到需要第三層目錄時就麻煩,再者Code是not null, ParentMenuCode是allow null , 是不是很奇怪…
3. ImageURL和RedirectURL 長度不一,一個是100,另一個是200。雖然好像太吹毛求瑕,但實際寫program時,要set input的max lenght就查一查長度都幾煩。

還有一些不方便公開ScreenShot的,例如Table名有空格,Primary Key / Constraints / Default value,應有則冇等等問題。
出現這些問題,原因就是設計的人沒有由Programming角度出發。
例如Table有空格,沒錯,看起來更清楚,但每次條Query都要用 [ ] (MSSQL) 或 ` ` (MySQL) Quote起來。
明明是應該Default是空白的卻可以Null,令到每次新增一條Record時都可能要特地Insert一個空白入去,或者相反用IsDBNull之類的Function是檢查,首當其衝當然是我這個寫Code的人。

所以現在你問我PM要不要識寫Program,我會答你至少都要”懂”。

2009年9月25日星期五

3分钟之内答错了 证明你不适合炒股票 (MC Question)

3分钟之内答错了 证明你不适合炒股票 (MC Question)


一道小学三年级数学题,3分钟之内答错了,证明你不适合炒股票!

您3分钟之内的答出的答案是错误的``证明你不适合炒股票!!

一天有个年轻人来到王老板的店里买了一件礼物

这件礼物成本是18元,标价是21元。

结果是这个年轻人掏出100元要买这件礼物。王老板当

时没有零钱,用那100元向街坊换了100元的零钱,找给年轻人79元。

但是街坊後来发现那100元是**

王老板无奈还了街坊100元。现在问题是:

王老板在这次交易中到底损失了多少钱 ?

每人只许发帖答一次,超过3分钟无效哦!!! (DONT CHEAT!!!!!!)

此题10个人作答有9人答错,印证炒股9赔1赚,非常灵验!!!

a) 97
b) 197
c) 121
d) 179
e) 200
f) u
g) 276

2009年8月7日星期五

男人最鍾意背住女人做咩﹖

你又做過邊幾樣﹖
作者: 黃貽興

女人最不能接受的事實是: 男人背著你是另一個人,網上是另一個人,女同事面前是另一個人,舊情人面前又是另一個人。
沒有一個女人能完全看清男人的全部面向,尤其是老婆。

因為通常老婆都只看到老公好的那部份,陽光照射不到的陰暗位,只有見不得光的身份,例如情婦二奶第三者,才能鉅細無遺看的見。
因此,這位置的女人,才比較立體而全面地看到這個男人的好與壞,而教她們著迷﹑不捨得離開的,就是因為男人的時好時壞。

有時候,當第三者,並不因為這位置風光獨好,不過是景觀較開揚罷了。在這位置,男人背住女人做的事,她們都比較能看的見。

1. 打飛機 一定會做的事。太重要了,所以放在最頭。男人不明白,為什麼同居女友或妻子那麼討厭﹑抗拒他們背著她偷偷打飛機。
對女人來說,這是側面質疑她們的吸引力和重要性的有力證明,但對男人來說,打飛機和打機,其實都很像,不過是用來打發時間和減壓罷了。

2. 跟ex聯絡 十個男人九個背著女人都會做的事。msn又好,見面都好;主動又好,被動都好……打飛機也許還能忍,但跟ex聯絡這心癮,實在無法抗拒。

3. 喪打機 女人問男人做咩無精神,尋晚唔係一齊收線訓覺咩﹖男人支支吾吾,查實收左線偷偷開機打,爆唔到死唔熄機,咪天光囉。
打機乃男人情意結,死症。冇得講。

4. 玩電器 男人對機器的耐性比女人好,能長時間沉迷其中。不管是玩相機﹑Hi Fi﹑煲碟﹑電腦或者任何能入電的東西,摸來搞去,樂此不疲。

5. 睇鹹帶 無論有冇受過高等教育﹑本身質素高低,或者性生活正唔正常﹑滿唔滿意,男人都鍾意無無聊click上鹹網睇,素人自拍﹑明星走光……

6. 玩公仔 大把麻甩鍾意拎住d萌系公仔著衫除衫又摸又砌,扭蛋又好figure又好,如癡如醉,對住女友都冇咁溫柔,嚇死。

7. 翻睇周星馳 次次睇親都比女友嫌,但男人其實好鍾意自己一支公無無聊睇返周星馳d舊戲。但女人每次見到都會鄙視地「唼」一聲,同埋話男人白癡。
女人唔明男人點解成日翻睇周星馳,男人都唔明女人點解成日翻煲《Sex and the City》。

8. 人體奧妙展 冇女人響身邊,男人好鍾意盡情un腳﹑兀凳﹑唔著拖鞋四圍踩﹑唔沖廁唔洗手跟手仲拎野食。
男人一個人既時候好鍾意用手指搣下鬍鬚,唔俾女人幫佢擠背脊既暗瘡,但就自己用手亂擠酒米。

9. 做壞事 sms同異性flirting﹑偷會第三者﹑扮單身約女同事﹑朋友或者網友出黎食飯睇戲,都係男人背住女人會做既事。
部份低質素男人好鍾意偷偷?骨唱邪K北上跳舞甚至叫雞。驚未﹖

10. 咩都唔做 基本上男人背住女人最鍾意做又最多做既,就係咩都唔做﹑發呆﹑攤屍。
男人唔明,點解女人一知道男人無野做一得閒就default要陪佢,唔陪就係罪。
所以男人欺欺瞞瞞,可能都只係為左可以咩都唔做,咩都唔諗。難得清靜。

聰明的男人,只是盡量擴大並展示自己的光明面;然而聰明的女人,卻是懂得不去發掘男人的陰暗面,同時裝作自己亮麗簡單,沒有陰暗面,讓男人放心。

2009年8月4日星期二

2009年7月15日星期三

何謂『射波』?

何謂『射波』?

秋高氣爽的某天,遊客多得很,每個遊樂設施也加派人手維持秩序。

「師兄,你做咩?呢邊出現?今日你應該?迴旋木馬…」我說。

「我畀人調過?幫手,你0個邊有兩個射波嘛﹗」格爾說。

「咩係射波?」我好奇地問。

近年,很多關於潮語的書籍也解釋過「射波」即偷懶、請病假之意,亦有解作故意裝病,騙取病假。射波這個詞彙原是旅遊業、服務業及飲食業的術語,後來廣泛流傳,各行各業的「打工仔」也廣用這個詞彙。但為什麼旅遊服務業率先使用「射波」詞彙呢?

射波=卸膊?就係咁簡單?

因為服務業是一個團隊工作,就如一支足球隊一樣,少了一個人,就要隊友替他分擔工作,就於「請病假」涉及而將工作轉嫁到別人身上的過程,是推卸責任及「卸膊」行為,而「射波」兩字廣東話發音與「卸膊」相近,所以就以「射波」解作故意裝病,善離職守。

就於「射波」一詞解釋眾說紛紜,為此請教一位不願公開姓名的大學教授,從他口中得知「射波」一詞的另一解釋。從前,老師們的點名簿、簽到簿,會在方格裡以剔號表示同學出席,一剔一點代表同學遲到,而畫一個圓圈,即代表缺席。由於方格就像一個龍門,而圓圈像皮球,圓圈畫在方格中心令人聯想到「射龍門」,久而久之,老師們便以「射波」去暗示同學請病假,例句:「阿邊個又『射波』。」

跟我學由「射波」而洐生出來的用詞

「射波」一詞廣為人知,但由「射波」而洐生出來的用詞,你又了解多小呢?

「波紙」、「入球證書」即是醫生給予病人的病假紙、醫生紙証明。

「梅開二度」即是醫生給予兩天病假。

「大三元」、「大演帽子戲法」即是醫生給予三天病假。

「大四喜」即是醫生給予四天病假。

「五連環」即是醫生給予五天病假。

「六合彩」即是醫生給予六天病假。

「七個一皮」即是醫生給予一星期的病假,是「詐病」最高境界。

「假動作」即是裝病裝得太作狀、過於明顯,例如用力扮咳,但咳不出聲。

「交叉走位」即是兩個人分別在兩個不同的上班時段去看醫生。

「試射」即是裝病去看醫生,看看醫生會否給予病假紙。

「射得入嗎?」一句暗語,用來問裝病的人能夠在醫生手上取得病假紙。

「前鋒」意指專門「射波」、態度懶散的同事。

「互射十二碼」意指下級請完病假,之後到上級請病假。

「射罰球」意指被上級發現裝病。

「守門員」意指盡責、忠心的員工,只接波不射波,病到七彩也堅持上班。總而言之,不止旅遊業、服務業,各行各業也有擅長「射波」的「戴志偉」、「小志強」,他們「射波」招式創新、一絲不會差……經過一大篇幅的解說何謂「射波」後,以下便是一件由朋友口中得知的「射波」趣事。

2009年3月3日星期二

物件導向 CSS

(轉載)
驟眼看來 Object Oriented CSS 好像不過是另一個 CSS Grid,但背後有其一道哲學,就是以 Object Oriented 的方式去寫 CSS (廢話),著重的是可以通過 code reuse,來分隔結構與皮膚、容器與內容。

可是這怎樣可以達成呢?CSS 本身並沒有所謂 Object 概念,其主要靠的是 Cascade,將 CSS Rules 一路堆疊下去。在這裏可以模擬到一點「繼承」特點,在同一個 tag 上使用多個 class (其實是 composition)。不過要真正做到很有規則,就要靠「自律」:自訂一些規則、實踐方法去跟從。

OOCSS 的方法是由「外到內」地如砌 LEGO 般建築頁面。先要弄好一個 template 檔,裏面只會包含一些 header、footer 等等基本的結構和一些基本元素如 heading、list 等等。然後做頁面時就可以使用 Line 和 Grid,來將這些容器細分為更細小的空間。最後才做內容。而理想的情況是,要做新頁或加入新的元素時,只要更動 HTML 就好。

不過因為 Cascade 特性,所有元素理論上也會繼承母元素的樣式,這當中可能要苦計一番 Specifity 和經常使用 !important 來 override 或 reset 樣式。另一個問題是,我們通常都不會第一時間想到最適合的結構和樣式,這當中又有沒有簡單的方法,如 Programming 般做到 Refactoring?

暫時放出來的 OOCSS 只有 template 和 Grid 的部份,以 YUI Grid 為基礎,暫時也很難從例子見到成效如何。(template 部份還連結錯 CSS…) 接下來還會有 Module Structures、Module Skins、Content objects 等等。且看發展如何?

2009年1月6日星期二

[轉載] 高性能網頁開發新20條規則詳解

上個月,Yahoo!優異性能(Yahoo!'s Exceptional Performance)開發團隊成員 Stoyan Stefanov 出席了蒙特利爾的2008魁北克PHP會議演講。他提供了他們團隊最新的研究成果和提高網頁性能規則20條。在早先的高性能網頁開發14條軍規已經讓大家耳熟能詳,此次新增的20條更加全面,覆蓋了伺服器端、cookies、頁面內容、JavaScript、CSS、圖片、移動手機應用這七大類別。以下內容就是根據這二十條結合個人在實際開發中的理解所做的全面解讀。希望對大家開發有所助益。

閱讀指導:

1. 每條規則後會指明是針對上述所說的七大類別中哪個類別的優化。

2. 文中提到的一些工具在文後附注中會提供簡要說明。

3. 文中經常提到“元件”這個詞,這個詞不同于我們程式開發中常提到的元件概念。本文中提到的“組件”特指嵌在HTML頁面中圖片、JavaScript腳本、CSS等靜態檔。

一、儘早清除緩衝區[伺服器端]

假如使用者請求一個頁面,而這個頁面在後端伺服器需要花200至500毫秒乃至更長時間才能生成最終HTML頁面,這時候使用者流覽器處於較長時間的、等待頁面資料返回的空閒狀態,使用者體驗不會很好。此時可以根據頁面內容長短做適當分隔,將先生成的頁面局部HTML緩衝內容提前發送到用戶端,不必讓伺服器消耗記憶體緩衝完整個龐大的頁面內容後再行輸出。這種方法有益於處理後端負荷大而前端負荷輕的頁面。

在HTML頁面的head標籤位置後是清除緩衝的好位置,因為HTML的head標籤可以包括 CSS 和 JavaScript 檔,對於流覽器而言獲取頁面顯示與後端伺服器處理並行的效果較好。在PHP中有一個函數 flush(),它可以發送請求頁面的局部HTML代碼給流覽器,以便流覽器能先取得頁面已經生成的部分HTML,同時後端伺服器繼續忙於處理生成頁面餘下的HTML。以下以此函數做個示例:view plaincopy to clipboardprint?
...









...

...









...
其他語言也有類似語法,如ASP.NET和ASP中的 Response.Flush()。

注意:在實際Web開發中,儘量減少HTTP請求次數是優化的重要方面,這條基本原則是早先14條和新增20條中很多規則的制訂基礎,實際上它也是14條規則中第一條也是非常重要的一條規則,但是使用儘早清除緩衝語句會增加一個頁面的HTTP請求次數,這無疑是一個矛盾,因此請注意本條規則的適用範圍,不要濫用它。


二、使用GET方法的AJAX請求[伺服器端]

這個容易理解一些。AJAX經常要用XMLHttpRequest,但是它的POST方法在流覽器中完成需要執行兩步:首先發送資訊頭,然後才是發送資料;而GET方法只用一個TCP資料包傳遞(cookies資訊例外)即可,減少了一個步驟,速度會快些。

另外根據HTTP規範,GET方法就是為獲取資訊而生的。因此僅在請求資料而不是發送資料給伺服器端存儲時,使用GET方法很有意義。

要注意的是,IE中URL允許最大允許長度是2K,用GET方法發送資料時注意2K的這個限制。


三、後載入元件[頁面內容]

使用該方法的意義在於:如果某個頁面內容豐富多彩的話,在流覽器載入顯示它時速度就不會很快。使用後載入元件的方法可以通過延遲載入一些隱藏內容來保證流覽器優先顯示初始頁面。

要做到這一點必須仔細觀察自己的頁面並且問自己:“解釋生成一個完整頁面,什麼部分內容是開始載入時絕對必須顯示的?”清楚了這個問題,那麼那些餘下內容和元件就可以採用後載入方法延遲生成。這樣會大大加快頁面顯示速度。

這個技巧通常是JavaScript通過處理頁面載入時的onload事件完成。例如,使用JavaScript代碼和庫去執行拖放動態效果操作時,這些操作可以延遲,因為拖動頁面上元素的操作只能等初始頁面生成完後才能發生。頁面中的隱藏內容也適合用後載入方式,因為只有頁面載入完畢使用者才能操作決定是否顯示該內容。

Yahoo!網站的首頁內容繁多,觀察處於隱藏狀態下的內容,這些內容通常在一些選項卡一樣的標籤頁當中,只有點擊後才會載入。

只要明白該規則的優化要點後相信大家可以通過JavaScript做出自己的具體實現。Yahoo!提供了兩個用於實現後載入方法的工具:

◆ YUI Image Loader:可以延遲圖片顯示

◆ YUI Get utility:它可以在頁面載入完成後把JavaScript和CSS資源綁定到DOM上去。

以上的工具是Yahoo!的YUI庫提供。


四、預載入元件[頁面內容]

從文字上看預載入元件與後載入元件似乎作用相反,但實際上二者目標是完全不同的。通過預先載入元件可以充分利用流覽器的閒置時間,並且可以請求未來頁面需要的元件。在這種情況下,當使用者訪問下一個頁面時,你已經提前讓大多數元件保存在緩存中,使用者載入這個頁面就會非常快。

預載入類型有下列三種:

1. 無條件預載入

onload事件一觸發,就要馬上取回一些指定的組件。可以檢查google.com首頁中onload事件中請求Sprite圖片的例子(注:什麼是Sprite圖片,請參看第十六條規則)。在這個例子可以看出這個sprite圖片:



在google.com首頁本身並不需要, 但它會在隨後使用者搜索生成的結果頁面中需要。

2. 條件預載入

根據使用者操作預測使用者下一步操作的方向,並據此做預載入。例如,search.yahoo.com中,在輸入框中剛鍵入幾個字元後,就會看到頁面對你鍵入的詞做出合理推測,推出幾個可能要搜索的實際關鍵字。此方法目前穀歌(google.cn)也在使用。

3. 提前預載入

在將重新設計的網站頁面發佈前用此法較好。頁面重新設計後常會有這樣的回饋:“新網站太酷了,就是比以前慢”。原因在於用戶訪問舊網站是全緩存的,但新網站還沒有緩存過。這時可以在發佈新設計前就預載入一些新網站元件,這可以減少沒有緩存的副作用。可以利用用戶訪問舊網站時流覽器空閒的時間請求新網站要使用的圖片、腳本等。


五、減少 DOM 元素數量[頁面內容]

一個複雜的頁面意味著要請求下載的位元組數更多,也意味著用JavaScript訪問DOM速度更慢。

如何儘量減少已有頁面的 DOM 元素數量呢?一個重要的思路就是不要濫用表格table和div 。很多人習慣用一些網頁編輯軟體去設計頁面,這樣會導致大量嵌套的表格或在使用語義不合法的標記。使用div要僅當它在語義上有意義時才使用它,有些開發者使用它僅僅是因為它可以被流覽器解釋生成一個新行。

Yahoo! 提供了一個避免這些問題的方法——使用YUI CSS工具。grids.css 有助於整體佈局設計,fonts.css 和 reset.css 有且於清除流覽器的默認格式設置。這些工具可以在Yahoo!的YUI頁面中去找。

DOM元素的數量可在Firebug的Console上鍵入 document.getElementsByTagName('*').length 得到。

DOM 元素不超過多少才適當呢?這可以通過檢查一些有良好設計的頁面來感覺比較。如Yahoo! 主頁訪問量相當大,它的數量在700個元素(HTML標籤)以下。


六、分隔元件到多個域中[頁面內容]

對終端使用者回應時間影響最大的就是所請求頁面所含元件數量。只要流覽器緩存為空,下載每個元件需要佔用額外的HTTP請求,只有緩存滿時才可能不佔用。

HTTP/1.1規範中建議流覽器對每一個主機名稱允許併發下載兩個元件。預設狀態下,Internet Explorer和Firefox都符合這個規範。注意:IE8.0默認允許6個併發請求。

許多網頁中所有元件都從同一主機名稱中下載,這時不僅回應時間受併發執行緒數限制,同時也受該伺服器CPU和頻寬限制。把頁面元件分佈在兩個主機名稱中,整體回應時間就會快2倍,CPU和頻寬消耗也會得以分擔。


七、儘量減少 HTML 標籤 iframe 的使用數[頁面內容]

iframe允許在父文檔內插入一個HTML文檔。要想高效使用iframes,理解它的工作方式很重要。

使用iframe有如下好處:

◆ 有助於減慢顯示協力廠商標記和廣告內容。

◆ 是個安全的 Sandbox。

◆ 能併發下載腳本。

但同時也有弊端:

◆ 即使iframe 內的 HTML 文檔內容為空,消耗也比較高。

◆ 會阻止頁面的onload事件

◆ 非語義的


八、避免404頁面[頁面內容]

如果做了一個HTTP請求然後得到一個無用的回應頁面,不僅完全不必要而且會降低用戶體驗。404頁面就是在沒有發現指定資源時返回的頁面。

一些網站提供了有益的404提示,對用戶體驗有好處,但這畢竟浪費了伺服器資源。當連結一個外部JavaScript檔,而它又出了404錯誤,這尤其糟糕。首先,因為這個下載有問題會阻止併發下載;其次,即使有錯流覽器仍然會盡力解析404返回的內容,看看有無JavaScript代碼,盡力查找裡面可用代碼。