4

現在社區維基!在服務器端級別呈現JavaScript。好的或壞的想法?

我想先說清楚:這不是關於服務器端JavaScript或運行Javascript服務器端的問題。這是一個關於從服務器端代碼呈現Javascript代碼(將在客戶端執行)的問題。

說了這麼多,看看下面ASP.net的代碼,例如:

hlRemoveCategory.Attributes.Add("onclick", "return confirm('Are you sure you want to delete this?');") 

這是處方在服務器端的客戶端onclick事件。

至於反對在客戶端編寫JavaScript:

$('a[rel=remove]').bind('click', function(event) { 
    return confirm('Are you sure you want to delete this?'); 
} 

現在我要問的問題是什麼是從服務器端代碼的JavaScript渲染的好處?或者反之亦然?

我個人比較喜歡客戶端UI /行爲掛鉤到HTML元素,原因如下的第二種方式

  • 服務器端做什麼都需要將已經包括DATA-驗證,事件委託等;和
  • 服務器端將哪些事件視爲事件不一定是客戶端上的相同進程。即在客戶端有更多的事件(只要看看自定義事件);和
  • 在客戶端和服務器端發生了什麼,在事件中,可能是完全不相關和解耦;和
  • 客戶端發生的事情發生在客戶端,沒有需要供服務器知道。服務器應該處理和運行給予他們的東西,如果發生客戶端事件,服務器如何實現它們並不是真正由他們決定的;等等等等。

這些是我的想法明顯。我想知道別人的想法,以及是否有任何關於這個話題的討論。

主題從這個論點分支可以達到:

  • 代碼管理:是更容易使一切從服務器端?
  • 分離問題:如果客戶端邏輯與服務器端邏輯分離,是否更容易?
  • 效率:在編碼和運行方面效率更高?

在一天結束時,我正試圖讓我的團隊走向第二種方法。這支隊伍中有很多老隊員都害怕這種變化。我只是想說服他們說正確的事實和數據。

讓我知道你的想法。

UPDATE1:看來我們所有參與這篇文章的人都有共同的想法;很高興知道有其他人也會這麼想。現在去說服這些傢伙;)謝謝大家。

+1

這應該是社區維基,因爲人們顯然根據他們的意見對答案投票,而不是基於信息的正確性。 – Guffa 2010-05-17 08:29:58

+0

正如你可以看到我的新手徽章,我不知道。我會查找如何將其轉變爲社區維基。感謝您的信息=) – hongymagic 2010-05-17 23:50:02

回答

3

你的第二個例子大大優於第一個例子。 Javascript是你的行爲層,應該與你的語義標記(內容)和CSS(表示)分開。這是更好的體系結構的一些原因:

  • 鼓勵逐步增強。正如你所提到的,後端代碼應該在沒有JS的情況下正常工作。你不能依靠你的客戶提供JS。通過這種方式,您可以在不使用JS的情況下構建它,然後使用JS增強體驗(例如,通過添加客戶端驗證以及服務器端驗證,以便客戶端可以獲得即時反饋)。
  • 清除標記。通常減少下載大小。一個單獨的JS文件中的可重用選擇器,可以在頁面之間緩存和共享,也可以在每個元素上處理器之間共享。
  • 所有的JS在一個重用的地方。例如如果你的代碼打開了一個彈出窗口,並且你決定改變窗口的尺寸,那麼你應該在JS文件的代碼中更改一次,而不必在每個單獨的內聯處理程序中更改它。

還有很多其他的論據和理由,但他們應該讓你開始...

此外,從你的例子看來,你有你的文檔中的正常鏈接,可以刪除的內容。這也是一個不好的做法。任何刪除或更新內容的內容都應該在POST(而非GET)請求上完成。所以它應該是提交表單的結果。否則例如googlebot可能會意外地通過抓取您的網頁來刪除您的所有內容(並且搜索引擎機器人不會執行JS,因此您的提醒無助於此)

+0

RE:刪除,當然是理論:)但點了。 – hongymagic 2010-05-18 05:50:38

+0

+1爲「逐步增強」 – hongymagic 2010-05-18 05:59:28

-1

對於您示例中的代碼,它並不重要。代碼沒有使用任何僅在服務器端可用的信息,因此在客戶端代碼中綁定事件同樣簡單。

有時你想使用一些信息,這些信息可在服務器端,以決定該事件是否應加入或沒有,或創建事件的代碼,例如:

if (categoryCanBeDeleted) { 
    hlRemoveCategory.Attributes.Add(
    "onclick", 
    "return confirm('Are you sure you want to delete the " + categoryType + "?');" 
); 
} 

如果您會在客戶端執行此操作,您必須以某種方式將此信息放入頁面中,以便客戶端代碼也可以訪問它。

+0

我會認爲這仍然是不好的做法。相反,你應該設置例如一個css類的元素,並在你的客戶端選擇器中使用它或者像在問題中的原代碼中一樣,你只能設置rel來刪除它應該做的刪除鏈接(與我的答案中的警告有關刪除任何東西無論如何,從GET鏈接) – vitch 2010-05-17 07:38:27

+0

爲了這個目的,我喜歡HTML5中的數據屬性。您可以在元素本身嵌入一條消息。例如:'Delete Account'。然後,Javascript可以拾取具有「data-delete」屬性的所有元素,並使用高度可定製的嵌入消息。 Rails 3在這樣的事情上下注很大,以減少JavaScript的混亂。 – Anurag 2010-05-17 08:01:48

+0

我同意維奇和阿努格在這裏。我認爲這篇文章已經有很多例子了。 – hongymagic 2010-05-18 05:46:38

3

我能想到的前面的 2個 最大的區別是:

  • 你失去客戶端緩存如果JavaScript是在一個單獨的JS文件
  • 如果你需要改變你會得到你的JavaScript,你必須重新編譯(推斷這發生在你發佈你的產品後會發生什麼:如果你必須重新編譯,那麼你需要重新分發二進制文件而不是隻是一個修改後的js文件)
  • 它更容易使用VS調試器如果javascript在一個單獨的文件中;你可以在該文件中設置一個斷點,如果你正在生成代碼服務器端,那麼你必須使用正在運行的文檔功能,找到你生成的代碼,然後添加斷點,並且每次你重新手動添加斷點 - 運行你的應用程序。接下來,如果代碼位於單獨的文件中,那麼您可以對JavaScript代碼,F5瀏覽器頁面進行調整,並繼續調試而不必停止並重新啓動調試器。

應該提到的是,有時你必須從服務器中插入JS代碼 - 例如,如果你的代碼的大部分是在一個單獨的js文件,你需要插入控制身份到該頁面的代碼跟...共事。儘可能避免這種情況。

+0

RE:控制身份 - 現在,使用jQuery等框架,在客戶端識別控件是一件容易的工作。通過css類屬性或任何其他自定義屬性,例如data-tooltip =「true」(顯然是在非XHTML頁面上)。我個人更喜歡定製屬性,因爲它提供了更多的靈活性。 我完全同意你關於重新編譯小型客戶端更改的代碼的觀點!很煩人。 – hongymagic 2010-05-17 23:53:45

1

看起來你已經知道該怎麼做了。在服務器端渲染它是個壞主意。

簡單的推理是你的Javascript生活在服務器端頁面以及單獨的Javascript文件(假設你使用的是Javascript)。當任何事物無處不在時,它可以成爲一個調試噩夢。如果您除了服務器端腳本生成的內容之外沒有使用任何其他Javascript,它可能會很好並且易於管理(忘記不引人注意的動作)。其次,如果頁面上有100個鏈接,則會在100個位置重複相同的代碼。重複是另一個維護和調試的噩夢。您可以使用一個事件處理程序和一個屬性處理所有頁面上的所有鏈接。這甚至不需要再想。

<Rant>

這是不容易的獨立的HTML和Javascript,甚至CSS特別是如果你想要一些AJAX或UI善良。爲了完全分離,我們必須移動到桌面應用程序模型,其中所有的前端代碼是,在客戶端使用Javascript編程生成,並且全部與服務器的交互限於純數據交換。

大多數上游通信(客戶端到服務器)已經只是數據交換,而不是下游通信。許多服務器端腳本生成HTML,將其與數據合併並吐出。只要服務器保持生成HTML視圖的命令,就沒有問題。但是,當花哨的Javascript出現在板上並開始將表追加到表中時,並且通過精確地複製現有HTML結構來註釋div,然後我們創建了生成標記的兩個點。

$(".comments").append($("<div>", { 
    "id": "123", 
    "class": "comment", 
    "html": "I would argue this is still bad practice..." 
})); 

也許這不是一個很大的噩夢(取決於規模),但它也可能是一個嚴重的問題。現在,如果我們更改註釋的結構,則需要在兩個位置完成更改 - 服務器端腳本和最初生成內容的模板,以及在頁面加載後動態添加註釋的Javascript端。

第二個示例是關於使用拖動和拖動的應用程序。如果您可以在頁面上拖動div,則需要將其從常規頁面流中取出,並用精確的座標絕對或相對定位。現在,由於我們無法事先爲所有可能的座標創建類(並且這對嘗試來說是愚蠢的),所以我們基本上直接在元素中注入樣式。然後,我們的HTML看起來像:

<div style="position: absolute; top: 100px; left: 250px;">..</div>

我們搞砸了我們美麗的語義頁,但它有許多工作要做。

</Rant>

語義和行爲分離之外,我想說的是基本上可以歸結爲重複。你是否不必要地重複代碼?多個層處理相同的邏輯。是否有可能將其全部推入單層,或者減少所有重複。

+0

好的咆哮。又一個補充:即使(serverside)生成的JavaScript代碼是動態的,並取決於應用程序狀態,分離成另一個.js文件並使用JSON將服務器端變量導出到頁面 - javascript是比生成更好的解決方案每個分支的不同代碼。 – Konerak 2010-05-18 06:04:11

0

您和其他回答問題的人已經列出了爲什麼最好不要讓服務器端代碼將內部事件屬性吐入文檔中的原因。

硬幣的另一面是,這樣做是快速簡單(至少在短期內)。

國際海事組織,這不會接近於超過方法的缺點,但它是一個原因。

相關問題