目前分類:HTTP protocol (4)

瀏覽方式: 標題列表 簡短摘要

由於 CGI 預設會先輸出 HTTP Status Code "200 OK",有些狀況卻會需要變更 HTTP Status Code,比如轉址,輸入帳密等。這個時候只要在第一行輸出 "Status: 302 Found\r\n" 即可。

參考網址:http://docstore.mik.ua/orelly/linux/cgi/ch03_03.htm

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()

CGI 環境變數包含很多有用的訊息,包含 AUTHORIZATION,QUERY_STRING,CONTENT_LENGTH 等。只要使用 getenv 函數直接讀取即可。如要讀取所有變數則使用 main 的第三個參數來分析。

參考網址:http://ccckmit.wikidot.com/cgi:env

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()

組織:中國互動出版網(http://www.china-pub.com/
RFC文檔中文翻譯計畫(http://www.china-pub.com/compters/emook/aboutemook.htm
E-mailouyang@china-pub.com
譯者:黃俊(hujiao  hj_chinese@yahoo.com
譯文發佈時間:2001-4-26
版權:本中文翻譯文檔版權歸中國互動出版網所有。可以用於非商業用途自由轉載,但必須
保留本文檔的翻譯及版權資訊。
  
  
Network Working Group                                           E. Nebel
Request For Comments: 1867                                   L. Masinter
Category: Experimental                                 Xerox Corporation
                                                           November 1995
  
                     HTML中基於表單的文件上傳
(RFC1867  Form-based File Upload in HTML)
  
本備忘錄的狀態
  
本備忘錄描述了一種Internet社區的試驗協議。本備忘錄並未規定任何Internet標準,它需
要進一步進行討論和建議以得到改進。本備忘錄的發佈不受限制。
  
目錄
1.摘要 2
2.帶有文件提交功能的HTML表單 2
3.建議採納的應用      3
3.1 FILE元件的顯示    4
3.2提交之後的動作     4
3.3 multipart/form-data的使用 4
3.4其他屬性的解釋     5
4.向後相容性的考慮     5
5.其他的考慮   6
5.1壓縮,加密  6
5.2文件傳輸延遲       6
5.3傳輸二進位資料的其他解決辦法       7
5.4 不修改      7
5.5欄位內容的默認類型 8
5.6允許ACTION指向"mailto:"   8
5.7第三方傳輸的遠端文件       8
5.8ENCTYPE=x-www-form-urlencoded來傳輸文件 8
5.9CRLF作為行分隔符號      8
5.10multipart/related的關係        9
5.11含有非ASCII碼的欄位名    9
6.例子  9
7. multipart/form-data的登記  10
8.安全性考慮   11
9.結論  11
作者地址:     12
A.multipart/form-data登記的媒體類型        12
參考:  13
  
1.摘要
  
目前,HTML的表單讓表單編寫者能夠通過表單得到流覽表單的用戶的資訊。在許多需要得
到用戶輸入的應用中,表單被證明是非常有用的。但是,因為HTML表單並沒有提供讓用
戶可以上傳檔或資料的途徑,這種能力受到了一定的限制。所以那些需要從用戶那兒得到
檔的服務提供商們不得不自己來建立相應的應用程式。(我們可以在www-talk郵件列表
中找到這類客戶流覽器的例子。)既然檔上傳是能夠讓許多應用程式受益的特點,這使得
人們要求擴展HTML,以便能讓資訊提供商們能夠統一地處理檔上傳請求,並為文件上傳
回應提供統一的MIME相容的表現形式。本方案同時也包括了一個向後保持相容的策略介
紹,以便能讓新的伺服器能和現有的HTML用戶端進行互動。
  
本建議獨立于現有的各版本HTML
  
2.帶有文件提交功能的HTML表單
  
現有的HTML規範為INPUT元素的TYPE屬性定義了八種可能的值,分別是:CHECKBOX, 
HIDDEN, IMAGE, PASSWORD, RADIO, RESET, SUBMIT, TEXT. 另外,當表單採用
POST方式的時候,表單默認的具有"application/x-www-form-urlencoded" ENCTYPE
屬性。
  
本建議對HTML做出了兩處修改:
1)為INPUT元素的TYPE屬性增加了一個FILE選項。
2INPUT標記可以具有ACCEPT屬性,該屬性能夠指定可被上傳的檔類型或檔格式
列表。
  
另外,本建議還定義了一種新的MIME類型:multipart/form-data,以及當處理一個帶有
ENCTYPE="multipart/form-data" 並且/或含有的標記的表單時所應該
採取的行為。
  
這些改變可以被視為是完全獨立的,但對於合理的檔上傳需求來說,這些改變都是必需的。
  
舉例來說,當HTML表單作者想讓用戶能夠上傳一個或更多的檔時,他可以這麼寫:
  
    
  
    File to process: 
  
    
  
    
  
HTML DTD裏所需要做出的改動是為InputType實體增加一個選項。此外,我們也建議用
一系列用逗號分隔的檔類型來作為INPUT標記的ACCEPT屬性。
  
  ... (其他元素) ...
  
  
                         RADIO | SUBMIT | RESET |
                         IMAGE | HIDDEN | FILE )">
  
  
          TYPE %InputType TEXT
          NAME CDATA #IMPLIED  -- required for all but submit and reset
          VALUE CDATA #IMPLIED
          SRC %URI #IMPLIED  -- for image inputs --
          CHECKED (CHECKED) #IMPLIED
          SIZE CDATA #IMPLIED  --like NUMBERS,
                                  but delimited with comma, not space
          MAXLENGTH NUMBER #IMPLIED
          ALIGN (top|middle|bottom) #IMPLIED
          ACCEPT CDATA #IMPLIED --list of content types
          >
  
  ... (其他元素) ...
  
3.建議採納的應用
  
因為用戶端有多種途徑來選擇最合適的方式來解釋HTML內容,本節針對其中的一種:
WWW流覽器來建議如何實現檔上傳。
  
3.1 FILE元件的顯示
  
當流覽器遇到一個FILE類型的INPUT標記時,它將顯示一個檔案名(或者是前面所選擇
的檔案名),和一個Browse(流覽)按鈕或類似的選擇方式。選擇這個Browse(流覽)
按鈕將觸發流覽器對應於其所運行的平臺相應的檔選擇方式。舉例來說,基於Windows
的流覽器將會彈出一個檔選擇視窗。在這個檔選擇視窗中,用戶可以進行替換現有的選
擇,為選擇增加一個新的檔等操作。流覽器的設計者可以自己確定所選擇的檔案名列表是
否可以被用戶手工修改。
  
如果該標記有ACCEPT屬性,流覽器還可以限制符合該平臺的檔類型。
  
3.2提交之後的動作
  
當用戶填完了表單,並且選擇了SUBMIT元素,流覽器應該將表單的內容和所選擇的檔
的內容傳回。對於傳送那些大容量的二進位資料或包含非ASCII字元的文本來說,
application/x-www-form-urlencoded編碼類型是遠遠不能滿足要求的。於是,我們提出了一
種新的媒體類型:multipart/form-data,用來作為將填寫好的表單內容從用戶端傳回到主機
端的高效方式。
  
3.3 multipart/form-data的使用
  
7節裏面對multipart/form-data做出了具體的定義。最極端的情況是選擇中不包括任何數
據。(這種選擇在某些情況下是非常可能的。)作為資料流程的一部分,表單中的每一項內容
都按照它們在表單中出現的順序被依次發送。每一部分由它們在HTML表單中INPUT標記
的名字所標識。如果該部分內容的類型是已知的,就用相應的媒體內容進行標識(舉例來說,
可以從檔的副檔名或者從作業系統的相關類型資訊中得知),否則的話,就標識為
application/octet-stream
  
如果有多個檔被選中上傳,它們必須按照multipart/mixed格式進行傳輸。
  
雖然HTTP協議能夠傳送任意形式的二進位資料,郵件傳送(舉例來說,如果表單的ACTION
mailto的形式)的默認方式是7位元編碼。但是如果傳送的內容和默認的編碼方式不相容
的話,所傳送的內容將需要進行編碼,並且加上一個"content-transfer-encoding"標識頭。
(此方面詳細內容可參看RFC 15215節)。
  
上傳檔的原始檔案名也應該一道被傳送,或者是作為filename參數,或者是
'content-disposition: form-data'的標題頭,如果傳送的是多個檔的話,也可以是子內容中
'content-disposition:file'的標題頭。用戶端應用程式應該儘量提供檔案名。如果用戶端操
作系統上的檔案名包含有非US-ASCII字元,檔案名可以用類似的字元或者是按照RFC1522
中描述的方法進行編碼。這在某些情況下有其便利之處,比如說上傳的檔中可能包含互相
關聯的關係,例如一個TeX檔可能會有一個尾碼為.sty的附加類型描述檔。
  
在伺服器端,ACTION可能是指向一個HTTP位址,借助CGI來完成表單的處理程式。在
這種情況下,CGI程式將會注意到內容類型是multipart/form-data,並採取措施來處理不同
的欄位(校驗合法性,按照處理順序將檔寫入磁片等等)
  
3.4其他屬性的解釋
  
標記可以有一個VALUE屬性來指定默認的檔案名。這有可能會影響到
平臺無關性,但也可能非常有用。舉例來說在某些有多個提交過程的操作中,可以避免讓用
戶不停的選擇同樣的檔案名。
  
可以用“SIZE=寬,高來指定SIZE屬性。寬度默認為檔案名的寬度,而高度是所選擇的
檔列表的顯示區域大小。舉例來說,對那些希望在流覽器中實現上傳多個檔,並且顯示
多行的檔輸入框(當然,旁邊還有一個Browse按鈕)的人來說,這點非常有用。當沒有
指定高度值時,將只會顯示一個單行的檔輸入框(如果表單設計者只希望上傳一個檔的
話),而如果高度值大於1的話,將顯示帶有捲軸的多行輸入框(如果表單設計者希望
上傳多個檔的話)。
  
4.向後相容性的考慮
  
儘管對於現有的WWW表單機制來說,一個成功的改進方案不一定要考慮這點,但是考慮
一種遷移的策略也是有幫助的:對於那些使用比較老版本的流覽器的用戶來說,借助於一個
附加程式,他們也能夠進行檔上傳。現有的絕大部分流覽器在碰到
時,會將它按照對待,並給用戶一個文本輸入框。用戶能在這個框
裏面輸入檔案名。此外,似乎現有的流覽器都忽略了表單元素中的ENCTYPE參數,並按
application/x-www-form-urlencoded傳送表單數據。
  
這樣的話,當伺服器端的CGI處理傳送回來的表單數據時,如果資料類型是
application/x-www-form-urlencoded,而不是multipart/form-data,就可以知道用戶使用的
流覽器沒有實現檔上傳。
  
在這種情況下,伺服器端的CGI不會返回一個“text/html”響應,而是返回一個資料流程以
便附加程式能夠處理;這個資料流程可能被標識為"application/x-please-send-files",並包含
以下內容:
  
?       表單數據實際需要被傳送至的(標準)URL位址(以CRLF結尾)
?       應該包含檔內容的欄位名字列表(用空格間隔開,以CRLF結尾)
?       用戶端傳至伺服器端的application/x-www-form-urlencoded表單數據
  
這時候,流覽器需要被設置以便能啟動一個附加程式來處理application/x-please-send-files
請求。
  
附加程式能夠處理表單數據,並且注意到那些包含有本地檔案名、需要用實際的檔內
容替代的欄位。它可能會需要提示用戶來改變或增加檔列表,然後重新將資料和檔內容
打包成multipart/form-data,並再次傳回給伺服器。
  
附加程式能夠象那些新版本的流覽器實際處理資料那樣處理表單,並按照原始的ACTION
指定的URL位址將資料發送。這樣處理的好處是伺服器端可以使用同樣的”CGI來處理
老版本及新版本的流覽器。
  
附加程式不需要顯示表單數據,但是需要確保用戶能夠得知傳送的檔是恰當的。(這
是為了避免那些不懷好意的伺服器要求傳送用戶本來沒有要求傳送的檔而可能帶來的安
全問題。)如果能夠顯示當前正在傳送的檔狀態,將非常有幫助。
  
5.其他的考慮
  
5.1壓縮,加密
  
本方案並沒有考慮可能存在的檔壓縮。經過一定的考慮,我們發現如果要讓流覽器自己來
決定那些檔需要被壓縮的話,對檔壓縮進行優化的討論將變得非常複雜。許多連接層的
傳輸協議(比如說高速數據機)在連接層對資料進行壓縮,如果在這一層上對壓縮進行
優化可能不是非常恰當。如果確實希望如此的話,可以讓流覽器選擇是否對檔內容進行
content-transfer-encodingx-compress壓縮,並且在伺服器端處理資料前進行資料解壓
縮。但這將不在該方案中進行討論。
  
同樣,本方案也沒有包括對資料進行加密的機制。這應該由其他的資料保密傳輸協定進行處
理,或者是保密HTTPHTTPs),或者是電子郵件。
  
5.2文件傳輸延遲
  
在某些情況下,在確實準備接受資料前,伺服器先對表單數據中的某些元素(比如說用戶名,
帳號等)進行驗證是推薦的做法。但是,經過一定的考慮後,我們認為如果伺服器想這樣做
的話,最好是採用一系列的表單,並將前面所驗證過的資料元素作為隱藏欄位傳回給客
戶端,或者是通過安排表單使那些需要驗證的元素先顯示出來。這樣的話,那些需要做複雜
的應用的伺服器可以自己維持事務處理的狀態,而那些簡單的應用的則可以實現得簡單些。
  
HTTP協定可能需要知道整個事務處理中的內容總長度。即使沒有明確要求,HTTP用戶端
也應該提供上傳的所有檔的內容總長度,這樣一個繁忙的伺服器就能夠判斷檔的內容是
否是過大以至於將不能完整地處理,從而返回一個錯誤代碼並關閉該連接,而不用等到接受
了所有的資料才進行判斷。目前一些現有的CGI應用對所有的POST事務都需要知道內容
總長度。
  
如果INPUT標記含有一個MAXLENGTH屬性,用戶端可以將這個屬性值看作是伺服器端
所能夠接受的傳送檔的最大位元組數。在這種情況下,伺服器能夠在上傳開始前,提示客戶
端在伺服器上有多少空間可以用來進行檔上傳。但是應該引起注意的是,這僅僅是一個提
示,在表單被創建後和檔上傳前,伺服器的實際需求可能會發生改變。
  
在任何情況下,如果接受的檔過大的話,任何一個HTTP伺服器都有可能在檔傳輸的
過程中中斷傳輸。
  
5.3傳輸二進位資料的其他解決辦法
  
有些人曾經建議使用一種新的MIME類型"aggregate",比如說aggregate/mixed 或是
content-transfer-encoding ""來描述那些不確定長度的二進位資料,而不是靠分解為多個
部分來表示。雖然我們並不反對這麼做,但這需要增加額外的設計和標準化工作來讓大家接
受並理解"aggregate"。 從另一方面來說,"分解為多部分"的機制工作得很好,能夠非常簡
單的在客戶發送端和伺服器接受端加以實現,而且能像其他一些綜合處理二進位資料的方式
一樣高效率地工作。
  
5.4 不修改
  
有些人曾經提到過,為什麼要修改INPUT來實現檔上傳功能,而不是為表單元素提供一
個完全不同的類型?在這種種考慮中,當我們使用時,最重要的考慮是相容策略。
事實上,標記"早就已經"被修改過以用來包含各種輸入的資料,相比較于創造不同
種類的標記,對進行加強看起來是更為合理的辦法。INPUT類型
並不是它所返回的內容類型,而更像是多類型的,也就是說,它表示了和用戶互動的方
式。它的定義被仔細地斟酌以便其既能在文本流覽器,也能在聲音標記中使用。
  
5.5欄位內容的默認類型
  
HTML中許多欄位都需要用戶進行輸入。過去人們對這些表單數據應該如何傳回到伺服器有
些意見分歧。但是將這些INPUT欄位的內容看成是純文本很明顯將有助於消除這方面的分
歧。用戶端再將這些數據傳回到伺服器以前應該將它們用CRLF分隔開,並進行適當的編
碼。
  
5.6允許ACTION指向"mailto:"
  
雖然和本方案無關,但是如果允許用戶端的表單的ACTION指向一個"mailto:"地址將肯定非
常有用。不管本方案本身怎麼設想,這都是一個好主意。同樣的,那些用來接受郵件的表單
ACTION也應該默認指向"reply-to:"。這兩個設想有助於讓HTML表單借助於HTTP服務
器工作,但通過電子郵件發送內容。或者也可以這麼做:允許HTML表單能夠被電子郵件
發送,當HTML中指明的郵件收件人填寫完表單後,再將結果發送作為郵件傳送回來。
  
5.7第三方傳輸的遠端文件
在某些情況下,那些操作用戶端軟體的用戶可能希望通過指定一個URL位址來傳送位於網
上,而不是本地的資料檔案。在這種情況下,流覽器能夠發送給客戶一個指向遠端資料的連
接,而不是實際的所有內容嗎?這種要求實際上是可以辦得到的,舉例來說,只要讓客戶在
發送給伺服器的資料當中,用"message/external-body"來指明資料的類型,同時將
"access-type"設置為連接的位址,並在發送的內容中包含遠端資料的URL位址就可以了。
  
5.8ENCTYPE=x-www-form-urlencoded來傳輸文件
  
如果一個表單包含了元素,但是表單本身未包含ENCTYPE屬性,也
就是沒有詳細說明相應的行為的話。這將可能導致為伺服器進行不恰當的對大量資料進行
URN編碼,而這將是伺服器端所不希望看到的
  
5.9CRLF作為行分隔符號
  
象所有的MIME傳輸一樣,在用POST方式傳送表單內容的時候,CRLF都被用作行的分
隔符。
  
5.10multipart/related的關係
MIMESGML小組正在考慮制訂一種新的類型,稱為multipart/related。它包含和
multipart/form-data類似的特點。Form-data的使用和應用卻是完全不同的,所以它被單獨
進行描述。
  
在某些情況下,有可能將HTML表單的內容(包括檔)作為multipart/related進行編碼,
但這和本方案所討論的情況有很大的不同。
  
5.11含有非ASCII碼的欄位名
  
需要注意的是MIME的標題頭通常是由7位的US-ASCII字元集構成。所以如果欄位名的字
符不屬於該字元集的話,就必須按照RFC 1522裏面所提到的方法進行編碼。在HTML 2.0
裏面,默認的字元集是ISO-8859-1,而由非ASCII碼字元組成的欄位名就必須進行編碼。
  
6.例子
  
假設伺服器段提供的是如下的HTML
  
     
           ENCTYPE="multipart/form-data"
           METHOD=POST>
     What is your name? 
     What files are you sending? 
     
  
用戶在姓名欄位裏面填寫"Joe Blow",對問題'What files are you sending?',用戶選擇
了一個文字檔案"file1.txt"
  
客戶段可能發送回如下的資料:
  
        Content-type: multipart/form-data, boundary=AaB03x
  
        --AaB03x
        content-disposition: form-data; name="field1"
  
        Joe Blow
        --AaB03x
        content-disposition: form-data; name="pics"; filename="file1.txt"
        Content-Type: text/plain
  
         ... file1.txt 的內容...
        --AaB03x--
  
如果用戶同時還選擇了另一個圖片檔"file2.gif",那麼用戶端可能發送的資料將是:
  
        Content-type: multipart/form-data, boundary=AaB03x
  
        --AaB03x
        content-disposition: form-data; name="field1"
  
        Joe Blow
        --AaB03x
        content-disposition: form-data; name="pics"
        Content-type: multipart/mixed, boundary=BbC04y
  
        --BbC04y
        Content-disposition: attachment; filename="file1.txt"
  
        Content-Type: text/plain
  
        ... file1.txt 的內容...
        --BbC04y
        Content-disposition: attachment; filename="file2.gif"
        Content-type: image/gif
        Content-Transfer-Encoding: binary
  
          ... file2.gif的內容...
        --BbC04y--
        --AaB03x--
  
7. multipart/form-data的登記
multipart/form-data的媒體內容遵從RFC 1521所規定的多部分的資料流程規則。它主要被用
來描述表單填寫後返回的資料。在一個表單中(這裏指的是HTML,當然其他一些應用也可
能使用表單),有一系列欄位提供給用戶進行填寫,每個欄位都有自己的名字。在一個確定
的表單中,每個名字都是唯一的。
  
multipart/form-data由多個部分組成,每一部分都有一個content-disposition標題頭,它的
值是"form-data",它的屬性指明了其在表單內的欄位名。舉例來說,'content-disposition: 
form-data; name="xxxxx"',這裏的xxxxx就是對應於該欄位的欄位名。如果欄位名包含非
ASCII碼字元的話,還應該按照RFC 1522裏面所規定的方法進行編碼。
  
對所有的多部分MIME類型來說,每一部分有一個可選的Content-Type,默認的值是
text/plain。如果檔的內容是通過表單填寫上傳返回的話,那麼輸入的檔就被定義為
application/octet-stream,或者,如果知道是什麼類型的話,就定義為相應的媒體類型。如
果一個表單返回多個檔,那麼它們就作為multipart/form-data中所結合的multipart/mixed
被返回。
  
如果所傳送的內容不符合默認的編碼方式的話,該部分都將被編碼,並加上
"content-transfer-encoding"的標題頭。
  
上傳的檔也可能被指定檔案名,檔案名可以由標題頭"content-disposition"中的filename
參數所指定。雖然這並不是必需的,但我們強烈建議在能夠得知原始檔案名的情況下這麼做。
對於很多應用程式來說,這都是必需的或者是有用的。
  
8.安全性考慮
  
如果用戶沒有明確要求發送某個檔,用戶端就不應該發送該文件,這點非常重要。所以,
在碰到的標記的時候,HTML解釋器應該能夠讓用戶確
認默認的檔案名。不要使用隱含的欄位來指定任何檔。
  
本方案並沒有包括對資料加密的討論;這應該是保密資料傳輸協議,或者是加密HTTP,或
者是MOSS所提供的加密協議(在RFC 1848中有具體的描述)所討論的問題。
  
一旦檔上傳成功,就將取決於檔接受方來處理檔或者是儲存在適當的地方。
  
9.結論
  
我們所建議的應用讓用戶端有很大的彈性來決定它發送到伺服器的檔的類型和數量,也讓
伺服器端有權決定是否接受上傳的檔,同時也讓伺服器有機會和那些不支持類型為file
INPUT的流覽器進行互動。
  
HTML DTD的改動雖然很簡單,但卻有很大的作用。能夠讓目前這種缺少檔上傳機制
的萬維網實現很多種服務。這將給萬維網實際的性能增加許多驚人的價值。
  
作者地址:
  
   Larry Masinter
   Xerox Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, CA 94304
  
   Phone:  (415) 812-4365
   Fax:    (415) 812-4333
   EMail:   masinter@parc.xerox.com
  
   Ernesto Nebel
   XSoft, Xerox Corporation
   10875 Rancho Bernardo Road, Suite 200
   San Diego, CA 92127-2116
  
   Phone:  (619) 676-7817
   Fax:    (619) 676-7865
   EMail:   nebel@xsoft.sd.xerox.com
  
A.multipart/form-data登記的媒體類型
媒體類型名稱:
 multipart
  
子類型名稱:
 form-data
  
必需的參數:
 
  
可選參數:
 
  
編碼考慮:
和其他類型相比沒有額外的考慮。
  
發行的規範:
 RFC 1867
  
安全性考慮
  
multipart/form-data並未引進新的安全性考慮來針對那些可能存在所附的內容中的問題。
  
參考:
  
[RFC 1521] MIME (多用途的網際郵件擴充協議) 第一部分:
          網上郵件內容格式的確定和規範機制
          N. Borenstein & N. Freed.
           19939.
  
[RFC 1522] MIME (多用途的網際郵件擴充協定) 第二部分:
          ASCII碼文本的郵件頭擴充
           K. Moore.
           19939.
  
[RFC 1806] 英特網上的資訊通訊和表達
           信息: Content-Disposition標題頭. 
          R. Troost & S. Dorner, 
          19956.
RFC 1867 Form-based File Upload in HTML       HTML中基於表單的文件上傳
RFC文檔中文翻譯計畫           1

 


台南小新 發表在 痞客邦 PIXNET 留言(1) 人氣()

傳送下列二個命令,就可以讓 browser 跳出驗證視窗。
fprintf(f, "HTTP/1.0 401 Unauthorized\n");

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()