成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何發送HTML表單數據

開發 前端
多數時候,HTML表單的目的只是為了把數據發給服務器,之后服務器再處理這些數據并發送響應給用戶。雖然看起來挺簡單的,但我們還是得注意一些事情以確保傳送的數據不會破壞服務器、或者給你的用戶制造麻煩。

多數時候,HTML表單的目的只是為了把數據發給服務器,之后服務器再處理這些數據并發送響應給用戶。雖然看起來挺簡單的,但我們還是得注意一些事情以確保傳送的數據不會破壞服務器、或者給你的用戶制造麻煩。

數據會到哪里去

關于客戶端/服務器架構

整個web都是基于一種基本的客戶端/服務器架構,該架構可以歸納如下:

一個客戶端(通常是Web瀏覽器)使用HTTP協議發送一個請求給服務器(通常是web服務器程序,譬如Apache, Nginx, IIS, Tomcat等等),而服務器則以相同的協議響應這個請求。

 

在客戶端,HTML表單只是提供一種比較方便且用戶友好的方式,用來配置發送給服務器的HTTP請求。這樣用戶就可以自己提供能被HTTP請求傳送的信息。

客戶端:定義如何發送數據

<form>元素能夠定義其數據如何被發送,它所有的特性都是為了在用戶點擊發送按鈕時,讓你配置要發送的請求。其中最重要的兩個特性是action和method。

action特性

該特性定義了數據會被發往何處,它的值必須是個合法的URL。若該特性未指定,則數據會發送到包含該表單的頁面所在的URL。

示例

在下面的例子中,數據會發送至http://foo.com

  1. <form action="http://foo.com"

這里,數據會被發送到表單頁所在的服務器,但到達的卻是服務器上不同的URL:

  1. <form action="/somewhere_else"

如下,當不指定任何特性時,表單數據會給發送到包含該表單的的頁面:

  1. <form> 

許多老舊的頁面會使用下面的符號來表明,數據得被發送到包含該表單的的頁面;這在當時是必須的,因為直到HTML5之前,action特性都是必填的。但現在就不再需要了。

  1. <form action="#"

注意:可以指定一個使用HTTPS(安全的HTTP)協議的URL,此時數據會隨請求的其他部分一起加密,即使表單本身位于一個通過HTTP訪問的不安全頁面。此外,若表單位于一個安全的頁面,而你卻給action特性指定了一個不安全的HTTP URL,則所有的瀏覽器會在每次用戶要發送數據時給他們一個安全警告,因為此時這些數據將不被加密。

method特性

該特性定義了數據如何被發送。HTTP協議提供了幾種方式來執行一個請求;HTML表單數據可以通過其中至少方式來發送:GET和POST。

要理解這兩種方式的不同,我們得回過頭來來看下HTTP是如何工作的。當你想取得Web上的某個資源時,瀏覽器會發送一個請求給指定的URL。一個HTTP請求含有兩個部分:包含和瀏覽器功能有關的一系列全局字段的請求頭,以及包含要給服務器處理的信息的請求體。

GET方法

瀏覽器使用GET方法來請求服務器發回指定的資源:“嘿服務器,我想獲得這個資源”。這種情況下,瀏覽器只會發送一個空的請求體,而正因如此,若瀏覽器使用該方式,那么發給服務器的數據會給追加到URL后面。

示例

考慮如下表單:

  1. <form action="http://foo.com" method="get"
  2.  
  3. <input name="say" value="Hi"
  4.  
  5. <input name="to" value="Mom"
  6.  
  7. <button>Send my greetings</button> 
  8.  
  9. </form>  

使用GET方法時,HTTP請求看起來就這樣:

  1. GET /?say=Hi&to=Mom HTTP/1.1 
  2.  
  3. Host: foo.com  

POST方法

POST方法則稍有不同,瀏覽器發送這個方法給服務器,用以請求一個和HTTP請求體里數據有關的響應:“嘿服務器,看看這些數據然后給我發回一個適當的結果”。若表單使用該方法發送,則數據會給追加到HTTP請求體里。

示例

考慮如下表單(和上面那個一樣):

  1. <form action="http://foo.com" method="post"
  2.  
  3. <input name="say" value="Hi"
  4.  
  5. <input name="to" value="Mom"
  6.  
  7. <button>Send my greetings</button> 
  8.  
  9. </form>  

使用POST方法時,HTTP請求看起來就這樣:

  1. POST / HTTP/1.1 
  2.  
  3. Host: foo.com 
  4.  
  5. Content-Type: application/x-www-form-urlencoded 
  6.  
  7. Content-Length: 13 
  8.  
  9. say=Hi&to=Mom  

Content-length頭部字段指示了請求體的大小,而Content-Type字段則標識了發往服務器的資源類型。我們將在稍后討論下這些請求頭。

當然,HTTP請求是不會展示給用戶看的(若你想看到它們,還得使用諸如火狐的Web Console或者chrome Developer Tools等工具),唯一展示給用戶的,只有訪問的URL。所以使用GET請求時,用戶將會在他們的地址欄看到數據,而使用POST請求則看不到。這點至關重要,原因如下:

  1. 若你要發送密碼(或者任何敏感數據),那千萬別用GET方法,否則該數據會不安全地展示在地址欄上。
  2. 若你想要發送大量數據,最好用POST方法,因為一些瀏覽器會限制URL的大小。此外,許多服務器也會限制接收的URL長度。

服務器端:處理數據

不論你選擇哪種HTTP方法,服務器只會接收到一個字符串并將其解析,再以鍵/值對列表的形式獲取數據。而如何訪問這個列表,取決于你基于何種開發平臺、以及用了何種框架。你使用的技術也會決定如何處理重復的鍵名,通常某個鍵名最后接收到的值是優先被選取的。

示例:原生PHP

PHP提供了幾個全局對象來處理數據。假設你使用POST方法,下面的示例會直接提取你的數據并展示給用戶。當然,要如何處理數據取決于你,你可以展示它、將其存進數據庫、用郵件發送它、或者其他任何方式。

  1. <?php 
  2.   // 全局變量$_POST讓你能夠訪問用POST方法發送的數據 
  3.   // 要訪問用GET方法發送的數據,可以使用$_GET 
  4.   $say = htmlspecialchars($_POST['say']); 
  5.   $to  = htmlspecialchars($_POST['to']); 
  6.  
  7.   echo  $say, ' ', $to 

這個示例會用我們發送的數據生成一個頁面。考慮我們前面用的表單示例數據,輸出結果會是: 

  1. Hi Mom 

示例:原生Python

下面的示例使用Python來做相同的事---將給定的數據展示到web頁面上。其中使用了CGI Python package 來處理表單數據。

  1. #!/usr/bin/env python 
  2. import html 
  3. import cgi 
  4. import cgitb; cgitb.enable()     # 用于處理錯誤 
  5.  
  6. print("Content-Type: text/html") # 請求頭字段,標識后面的內容是HTML 
  7. print()                          # 空行,表示請求頭的結束 
  8.  
  9. form = cgi.FieldStorage() 
  10. say  = html.escape(form["say"].value); 
  11. to   = html.escape(form["to"].value); 
  12.  
  13. print(say, " "to 

結果和之前用PHP處理是一樣的:

  1. Hi Mom 

其它語言和框架

還有許多其他的服務端技術可以用來處理表單,比如Perl, Java, .Net, Ruby等等,選擇你最喜歡的一種就好。我們很少直接使用這些技術,因為這么做得需要很多技巧來填坑;通常我們會在眾多好用的框架中選擇一種,這樣會讓表單的處理更容易些,比如:

  • Symfony for PHP
  • Django for Python
  • Ruby On Rails for Ruby
  • Grails for Java

值得注意的是,就算用了這些框架,處理表單是不一定就會變得輕松。但至少這樣用起來會更好些,還能節省你不少時間。

特殊案例:發送文件

文件是HTML表單中一個特殊的例子,其他數據都是文本數據,而文件則一般是、或者被認為是二進制數據。由于HTTP是個文本協議,所以對處理二進制數據得有特別的要求。

enctype特性

該特性能讓你指定HTTP請求頭中的Content-Type字段值,這個字段的重要性在于,它能告訴服務器要發送的數據類型。其默認值是application/x-www-form-urlencoded,對應的解釋是:“這份表單數據已被編碼為URL格式”。

而當你想發送文件時,得先做兩件事:

  • 將method特性設置為POST,因為使用表單時,文件內容是不能被放到URL參數里的
  • 將enctype特性的值設為multipart/form-data,這樣數據就會被分割為多個部分,每個文件都會追加上和他們一起發送的表單有關的文本。

示例: 

  1. <form method="post" enctype="multipart/form-data"
  2.  
  3. <input type="file" name="myFile"
  4.  
  5. <button>Send the file</button> 
  6.  
  7. </form>  

注意:某些瀏覽器支持<input>元素的multiple特性,以便讓一個input元素能發送多個文件。至于服務器會如何處理這些文件,就得取決于它用來什么技術了。如前所述,使用框架能讓你的活的輕松些~

警告:為防止濫用,許多服務器會對文件和HTTP請求設置大小限制。所以,最好在發送文件之前和服務器管理員核實一下這個限制。

安全相關

每次要發數據給服務器前,你都得考慮下安全問題。HTML表單是針對服務器的首要攻擊載體之一,但該危害的來源并非HTML表單本身,而在于服務器如何處理數據。

常見的安全問題

著名的安全問題有很多,如何劃分取決于你在做什么:

XSS和CSRF

跨站腳本攻擊(XSS)和跨站請求偽造(CSRF)是最常見的攻擊類型,它們會在你展示由用戶發給用戶的數據時發生。

XSS讓攻擊者能再其他用戶訪問的Web頁面上注入客戶端腳本。攻擊者會利用跨站腳本的脆弱性來繞過訪問控制策略,譬如同源策略。這種攻擊可以取得從小麻煩到嚴重安全危機不等的危害效果。

CSRF很像XSS,因為它們都以相同的方式開始---注入客戶端腳本到Web頁面,但它們的攻擊目標卻不同。CSRF攻擊者會試著升級權限以成為一個高權限的用戶(比如網站管理員),然后執行本不能夠執行的動作(如把數據發送給不受信任的用戶)。

XSS攻擊利用了用戶對網站的信任,而CSRF攻擊則利用了網站對其用戶的信任。

要防止此類攻擊,就得時常校驗用戶發送給服務器的數據;同時(如果需要展示)也盡量別展示用戶提供的HTML內容,而應該處理用戶提供的數據,以避免將其原封不動地顯示出來。目前幾乎所有市面上的的框架,至少都會實現一個過濾器,用以移除用戶提交數據中<script>, <iframe>, <object>等標簽,這樣有助于減輕風險,但并不意味著會根除它。

SQL注入

SQL注入是一種對目標網站的數據庫執行動作的攻擊方式。通常攻擊者會發送一段SQL請求,并希望服務器能執行它(多數發生在應用服務器想存儲數據之時)。這實際上已成為針對web站點的主要攻擊載體之一。

該攻擊的危害是很嚴重的,小到數據丟失、大到被攻擊者通過權限升級訪問整個網站架構。這確實是非常重大的威脅,所以你不應該存儲那些用戶提交而沒經過特殊處理(例如,在PHP/MySQL架構下經過mysql_real_escape_string()處理)的數據。

HTTP頭部注入和郵件注入

這種攻擊會在你的應用使用用戶在表單上輸入的數據來構造HTTP頭、或者email時發生。該攻擊雖然不會危害你的服務器或者影響你的用戶,但卻會給更深處的問題大開方便之門,比如會話劫持、釣魚攻擊。

所有這些攻擊往往都是悄無聲息地發生的,而且會把你的服務器弄成肉雞)。

偏執些:永遠別信任你的用戶

所以,要如何對抗這些威脅呢?這一點已超出本指南的主題范圍了,但有幾條規則時需要我們牢記的。最重要的一條就是:永遠別信任你的用戶,包括你自己;即使是受信任的用戶也會有被劫持可能。

所有的到達你服務器的數據都必須被校驗并處理,而且要一直保持,不能有例外。

  • 過濾潛在的危險字符。要關注的哪些特定字符,取決于使用數據的上下文、也取決于你使用的服務器平臺,而所有的服務端語言都會提供相應的功能。
  • 限制傳入的數據量,只允許有必要的。
  • 把上傳的文件放沙盒里(將它們存儲到放到一個不同的服務器上,并且要訪問到它們只有通過一個不同的子域名、或一個完全不同的域名才行)。

若你能遵循這三條規則,就應該能避免絕大多數問題,但一個更好的辦法是讓一個有資格的第三方來做安全審查,別以為你能看透所有潛在的問題。

結論

如你所見,發送表單數據時很簡單的,但保障一個應用的安全就需要很多技術了。前端開發者不是那種去定義一個數據安全模型的角色,雖然可能得執行[客戶端數據校驗](),但是服務器也不能信任這些校驗,因為它并不能確切知道客戶端上到底發生過什么。

參見

若你想學習更多關于wep應用安全防護的知識,可以深入了解下面這些資源:

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2023-04-26 08:18:48

FormPrompt表單更改

2011-07-22 09:51:51

iPhone FROM 表單

2009-07-03 14:41:03

2009-07-02 15:12:39

2016-12-13 13:54:10

EasyUI form數據加載

2012-06-05 10:15:43

jQuery

2010-06-10 18:08:58

2009-07-02 11:29:22

JSP技術表單數據存儲

2021-09-14 18:33:39

React 數據交互

2009-12-01 18:02:41

PHP表單數組

2022-04-10 23:43:11

代碼發送郵件后端

2011-02-23 14:57:41

webweb開發HTML

2011-07-25 16:32:08

HTML 5

2022-11-14 10:44:59

HTMLFlowable外置

2020-10-10 08:49:02

JS

2020-10-10 08:01:38

JS HTML 表單

2017-06-22 16:00:07

數據庫NoSQL遷移實踐

2009-06-30 11:18:16

HTML表單JSP教程

2011-02-24 11:10:40

2023-04-24 16:08:09

JavaScripHTMLPDF
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩精品中文字幕 | 精品视频在线观看 | 亚洲精品一二三 | 国产精品美女www爽爽爽 | 日本在线视频一区二区 | 日韩视频免费看 | 操操操操操 | 亚洲精品一区二三区不卡 | 久久国产精品-久久精品 | 色嗨嗨| 久久久久久99 | 色综合久久天天综合网 | 日本三级电影在线看 | av大片 | 国产中文字幕在线观看 | 国产精品久久久久久婷婷天堂 | 秋霞在线一区二区 | 欧美性网 | 91网站在线播放 | 久久艹免费视频 | 天天干天天爱天天爽 | 中文字幕一区二区三区不卡在线 | 伊人婷婷 | 亚洲精视频 | 米奇成人网 | 欧美a区 | 国产欧美在线播放 | 久久中文一区二区 | 福利视频一区二区 | 国产日屁 | 天天爽网站 | 激情婷婷 | 欧美视频一区二区三区 | 老司机成人在线 | 免费观看的av毛片的网站 | 青青草一区二区 | 成人精品一区二区 | 99精品久久 | 国产精品久久久久久久久久 | 久久免费视频1 | 翔田千里一区二区 |