Javascript诞生记
- Milido - 阮一峰的网络日志二周前,我谈了一点Javascript的历史. 今天把这部分补全,从历史的角度,说明Javascript到底是如何设计出来的. 只有了解这段历史,才能明白Javascript为什么是现在的样子. 我依据的资料,主要是Brendan Eich的自述. "1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.
使用者在點擊網頁元素後啟動檔案下載的方法有好幾種,我做了一個ASP.NET網頁一次測試window.open(), location.href, 隱藏iframe等三種方法,同時還加個Checkbox以模擬下載失敗顯示錯誤訊息網頁的情境。
<%@ Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
if (Request["mode"] == "download")
{
if (Request["err"] == "1")
//To simulate failed download
Response.Write("<html><body>Failed to Download File!</body></html>");
else
{
Response.AddHeader("content-disposition",
"attachment;filename=text.txt");
Response.ContentType = "application/octet-stream";
Response.Write("Darkthread Test");
}
Response.End();
}
}
</script>
<html>
<head runat="server">
<title>Download Test</title>
<script type="text/javascript"
src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.js"></script>
<script type="text/javascript">
$(function () {
$(":button").click(function () {
var dlLink = "Download.aspx?mode=download&err=" +
$("#err:checked").length;
switch (this.id) {
case "b1":
window.open(dlLink);
break;
case "b2":
location.href = dlLink;
break;
case "b3":
var $ifrm = $("<iframe style='display:none' />');
$ifrm.attr("src", dlLink);
$ifrm.appendTo("body");
$ifrm.load(function () {
//if the download link return a page
//load event will be triggered
$("body").append(
"<div>Failed to download <i>'" + dlLink + "'</i>!");
});
break;
}
});
});
</script>
<style type="text/css">
.btn input
{
display: block;
width: 200px; height: 30px;
margin: 10px;
text-align: center;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<input type="checkbox" id="err" />Failed Download
<div class='btn'>
<input type="button" id="b1" value="Download with window.open" />
<input type="button" id="b2" value="Download with location.href" />
<input type="button" id="b3" value="Download with hidden iframe" />
</div>
<div id="msg"></div>
</form>
</body>
</html>
以下是簡單的分析比較:
比較之下,個人偏好iframe法,至於無法偵測下載出錯的問題,我發現<iframe>有個特性: 當src指向的連結是一般網頁,$(iframe).load()事件會被觸發,指向下載檔案連結時則不會。利用此差異,我們可以在load()事件中加入下載失敗提醒,因為load()一旦被執行就代表下載失敗。原本另一個想法是try catch所有錯誤並傳回一段Javascript,彈出alert()或修改父頁面元素顯示資訊,但這個做法對HTTP 404或500錯誤無效,比較之下,load()事件法還是較好的解決方案。