httpput上傳文件
① ASP文件上傳原理分析及實現實例
摘要 在基於/的應用環境中 上傳各種類型的文件一直是困擾用戶文件管理應用的難題之一 在HTTP中上傳文件有三種機制 RFC PUT和WebDAV 常用的實現方法是利用在RFC 中引入的一個新類型 File以及ADO Stream對象 本文對上述上傳方法及實現原理作了論述 並給出了具體解決實例 ASP FILE對象
當前 基於/模式的應用比較流行 當用戶需要將文件傳輸到上時 常用方法之一是運行ftp並將每個用戶的FTP默認目錄設為用戶的Web主目錄 這樣用戶就能運行FTP客戶程序並上傳文件到指定的 Web目錄 這就要求用戶必須懂得如何使用FTP客戶程序 因此 這種解決方案僅對熟悉FTP且富有經驗的用戶來說是可行的 如果我們能把文件上傳功能與Web集成 使用戶僅用Web就能完成上傳任務 這對於他們來說將是非常方便的 但是 一直以來 由於File System Object的僅能傳送文本文件的局限 所以ASP最大的難題就是文件上傳問題 下面介紹的就是如何在基於HTTP協議的網頁中實現文件的上傳
一 通過HTTP上傳的三種機制
通過HTTP上傳有三種機制 RFC PUT 和 WebDAV
PUT 是在HTTP 引入了一個新的HTTP動詞 當web收到一個HTTP PUT和對象名字 它將會驗證用戶 接收HTTP流的內容 並把它直接存入web 由於這可能會對一個web站點造成破壞 並且還會失去HTTP最大的優勢 可編程性 在PUT的情況下 自己處理請求 沒有空間讓CGI或者ASP應用程序介入 唯一讓你的應用程序捕獲PUT的方法是在低層操作 ISAPI過濾層 由於相應的原因 PUT的應用很有限
而WebDAV允許web內容的分布式拆吵認證與翻譯 它引入了幾種新的HTTP動詞 允許通過HTTP上傳 鎖定/解鎖 登記/檢驗web內容行御知 Office 中的 Save to web 就是通過WebDAV來實現的 如果你所感興趣的一切都是上傳內容 WebDAV應用得非常出色 它解決了很多問題 然而 如果你需要在你的web應用程序裡面上傳文件 WebDAV對你就毫無用處可言 象HTTP PUT一樣 那些WebDAV的動詞是被解釋的 而不是web應用程序 你需要工作在ISAPI過濾層來訪問WebDAV的這些動詞 並在你的應用程序中解釋內容
RFC () 最終被W C在HTML 中接受前 是作為一種建議標准 它是一種非常簡單但是功能很強大的想法 在表單欄位中定義一個新類型 <INPUT TYPE= FILE >
並且在表單本身加入了不同的編碼方案 不再使用典型的 <FORM ACTION= formproc asp METHOD= POST > 而是使用 <FORM ACTION= formproc asp METHOD= POST ENCTYPE= multipart/form data >這種編碼方案在傳送大量數據的時候 比起預設的 application/x url encoded 表單編碼方案 顯得效率要高得多 URL編碼只有很有限的字元集 使用任何超出字檔消符集的字元 必須用 %nn 代替 這里的nn表示相應的 個十六進制數字 例如 即使是普通的空格字元也要用 % 代替 而RFC 使用多部分MIME編碼 就象通常在e mail消息中看到的那樣 不編碼來傳送大量數據 而只是在數據周圍加上很少的簡單但實用的頭部 主要的廠商都採用了建議的 瀏覽…… 按鈕 用戶能很容易的使用本地 打開文件…… 對話框選擇要上傳的文件
RFC 仍然將大多數文件上傳的靈活方法留給了你的web應用程序 PUT用得很有限 WebDAV對內容的作者很有用 比如FrontPage用戶 但是對想在web應用程序中加入文件上傳的web開發者來說很少用到 因此 RFC 是在web應用程序中加入文件上傳的最好的辦法
在實際應用中 免費提供了Posting Acceptor ASP不懂 multipart/form data 編碼方案 取而代之 提供了Posting Acceptor Posting Acceptor是一種在上傳完成後 接受REPOST到一個ASP頁的ISAPI應用程序
Sofare Artisans的SA FileUp是最早的商業Active Server之一 幾經改進 現在作為一個純粹的ASP存在
二 基於ASP的文件上傳實現原理分析
基本原理是 採用ADO Stream對象的BinaryRead方法將FORM中的所有數據讀出 從中截取出所需的文件數據 以二進制文件方式存檔
下面是上傳文件頁面的一個例子() <><body><form name= Upload Method= Post Enctype= multipart/form data Action= Upload asp ><input type= file name= FileName ><INPUT TYPE= Submit VALUE= Upload ></TD></form></body></>
程序中使用了文件對象 這樣在Upload asp中採用BinaryRead方法讀來的原始數據就不僅僅是選擇的文件本身的數據 還包含該文件在用戶硬碟上的路徑 類型 提交頁面的表單等相關信息的描述 這樣我們就需從中提取出文件的具體內容 根據分析 數據的頭部信息與數據的分界線是兩對回車換行符 尾部也有分隔信息 我們可以採用類似以下的方法獲取文件數據 Dim FormData FormSize DataStart CLStr DivStrFormSize=Request TotalBytesFormData=Request BinaryRead(FormSize)CLStr=ChrB( )&ChrB( )DataStart=InStrB(FormData CLStr&CLStr)+ 是兩對回車換行符的長度DivStr=LeftB(FormData InStrB(FormData CLStr) )DataSize=InStrB(DataStart+ FormData DivStr) DataStart FormData=MidB(FormData DataStart DataSize) FormData就是文件的內容了 中間根據需要 可進行相應的處理 最後的工作就是將文件保存了 保存的方法可以有兩種 一種是利用VB或VC之類程序中的二進制文件操作方法 在工程中加入適當的類型庫 最終編譯成DLL文件 使用時再將該DLL文件注冊就可以了 文件存貯程序如下 Public Function SaveFile(Pathname As String) As String Dim objContext As ObjectContext Dim objRequest As Request Set objContext=GetObjectContext() Set objRequest=objContext( Request ) 以下的一段代碼是進行文件存貯的有關操作Dim FormData() As Byte CLStr DivStr Dim DataStart As Long DataSize As Long DataSize=objRequest TotalBytes Redim FormData(DataSize ) FormData=objRequest BinaryRead(DataSize) CLStr=ChrB( ) & ChrB( ) DataStart=InStrB(FormData CLStr & CLStr)+ DivStr=LeftB(FormData InStrB(FormData CLStr) ) DataSize=InStrB(DataStart+ FormData DivStr) DataStart FormData=MidB(FormData DataStart DataSize) 創建一個二進制文件並將FormData寫入其中 Open Pathname For Binary As Put # FormData Close # SaveFile= OK! End Function 第二種方法是利用ADO STREAM中提供的二進制文件操作方法來完成 保存文件的語句是 StreamOBJ SaveToFile (fileName ) 在 這種操作中 我們可以將有關的操作存放在一個類文件中 在應用時 直接將該類文件包含在ASP程序中就可以了 具體處理方法 請參閱有關介紹 三.文件上傳實現方法實例 實現文件上傳可使用或無方式 對於類 比如說microsoft posting acceptor(簡稱mpa) 就是公司發布的一個免費 這類的安裝也比較方便 對於的mpa 運行它的安裝文件就可以了 而一般的dll形式的 我們則需要進行注冊 例如 要使用aspcnUP dll 只要在Window 上執行regsvr [path]aspcnUP dll 系統出現注冊成功的信息提示就可以使用該了 對於無類 如的無上傳類 upload_ xsoft 在使用時 只要在處理程序中包含以下的語句就可以了 <! #include FILE= upload inc >set upload=new upload_ xSoft 建立上傳對象 有關的屬性與操作方法 請參閱該的使用手冊 下面是詀spcnUP dll為例 上傳部分類型文件的源代碼(upload asp) <% @ language= vbscript Set fileUP=Server CreateObject( aspcn Upload )fileUP Maxsize= fileUP Path= d:upfile fileUP UploadFor i= to fileUP Countfieldname=fileUP FieldName(i)If fileUP FileType(fieldname)= zip Or ileUP FileType(fieldname)= rar ThenfileUP Save fieldnameEnd If NextSet fileUP=Nothing%> 四.結束語 應用模式還在快速地發展著 在ASP.NET中 已經內置了文件上傳的功能 使用非常簡單方便 作為一種全新的技術 ASP.NET並不只是ASP的簡單升級 它是一個用於Web開發的全新框架 其中包含了許多新的特性 ASP.NET提供了更易於編寫 結構更清晰的代碼 利用這些代碼我們將會更容易地進行再利用和共享 從而開發出更多更實用的程序來 lishixin/Article/program/net/201311/13562
② FTP,HTTP……等計算機協議及解釋...
FTP(File Transfer Protocol),是文件傳輸協議的簡稱。用於Internet上的控制文件的雙向傳輸。同時,它也是一個應用程序(Application)。用戶可以通過它把自己的PC機與世界各地所有運行FTP協議的伺服器相連,訪問伺服器上的大量程序和信息。
基本簡介FTP正如其名所示FTP的主要作用,就是讓用戶連接上一個遠程計算機(這些計算機上運行著FTP伺服器程序)察看遠程計算機有哪些文件,然後把文件從遠程計算機上拷到本地計算機,或把本地計算機的文件送到遠程計算機去。
當啟動FTP從遠程計算機拷貝文件時,事實上啟動了兩個程序:一個本地機上的FTP客戶程序:它向FTP伺服器提出拷貝文件的請求。另一個是啟動在遠程計算機的上的FTP伺服器程序,它響應你的請求把你指定的文件傳送到你的計算機中。FTP採用「客戶機/伺服器」方式,用戶端要在自己的本地計算機上安裝FTP客戶程序。FTP客戶程序有字元界面和圖形界面兩種。字元界面的FTP的命令復雜、繁多。圖形界面的FTP客戶程序,操作上要簡潔方便的多。
FTP支持FTP協議的伺服器就是FTP伺服器,下面介紹一下什麼是FTP協議。用戶聯網的首要目的就是實現信息共享,文件傳輸是信息共享非常重要的一個內容之一。Internet上早期實現傳輸文件,並不是一件容易的事,Internet是一個非常復雜的計算機環境,有PC,有工作站,有MAC,有大型機,據統計連接在Internet上的計算機已有上千萬台,而這些計算機可能運行不同的操作系統,有運行Unix的伺服器,也有運行Dos、Windows的PC機和運行MacOS的蘋果機等等,而各種操作系統之間的文件交流問題,需要建立一個統一的文件傳輸協議,這就是所謂的FTP。基於不同的操作系統有不同的FTP應用程序,而所有這些應用程序都遵守同一種協議,這樣用戶就可以把自己的文件傳送給別人,或者從其它的用戶環境中獲得文件。
工作原理FTP與大多數Internet服務一樣,FTP也是一個客戶機/伺服器系統。用戶通過一個支持FTP協議的客戶機程序,連接到在遠程主機上的FTP伺服器程序。用戶通過客戶機程序向伺服器程序發出命令,伺服器程序執行用戶所發出的命令,並將執行的結果返回到客戶機。比如說,用戶發出一條命令,要求伺服器向用戶傳送某一個文件的一份拷貝,伺服器會響應這條命令,將指定文件送至用戶的機器上。客戶機程序代表用戶接收到這個文件,將其存放在用戶目錄中。
在FTP的使用當中,用戶經常遇到兩個概念:「下載」(Download)和「上載」(Upload)。「下載」文件就是從遠程主機拷貝文件至自己的計算機上;「上載」文件就是將文件從自己的計算機中拷貝至遠程主機上。用Internet語言來說,用戶可通過客戶機程序向(從)遠程主機上載(下載)文件。
使用FTP時必須首先登錄,在遠程主機上獲得相應的許可權以後,方可上載或下載文件。也就是說,要想同哪一台計算機傳送文件,就必須具有哪一台計算機的適當授權。換言之,除非有用戶ID和口令,否則便無法傳送文件。這種情況違背了Internet的開放性,Internet上的FTP主機何止千萬,不可能要求每個用戶在每一台主機上都擁有帳號。匿名FTP就是為解決這個問題而產生的。
匿名FTP是這樣一種機制,用戶可通過它連接到遠程主機上,並從其下載文件,而無需成為其注冊用戶。系統管理員建立了一個特殊的用戶ID,名為anonymous,Internet上的任何人在任何地方都可使用該用戶ID。
通過FTP程序連接匿名FTP主機的方式同連接普通FTP主機的方式差不多,只是在要求提供用戶標識ID時必須輸入anonymous,該用戶ID的口令可以是任意的字元串。習慣上,用自己的E-mail地址作為口令,使系統維護程序能夠記錄下來誰在存取這些文件。匿名FTP不適用於所有Internet主機,它只適用於那些提供了這項服務的主機。
當遠程主機提供匿名FTP服務時,會指定某些目錄向公眾開放,允許匿名存取。系統中的其餘目錄則處於隱匿狀態。作為一種安全措施,大多數匿名FTP主機都允許用戶從其下載文件,而不允許用戶向其上載文件,也就是說,用戶可將匿名FTP主機上的所有文件全部拷貝到自己的機器上,但不能將自己機器上的任何一個文件拷貝至匿名FTP主機上。即使有些匿名FTP主機確實允許用戶上載文件,用戶也只能將文件上載至某一指定上載目錄中。隨後,系統管理員會去檢查這些文件,他會將這些文件移至另一個公共下載目錄中,供其他用戶下載,利用這種方式,遠程主機的用戶得到了保護,避免了有人上載有問題的文件,如帶病毒的文件。
作為一個Internet用戶,可通過FTP在任何兩台Internet主機之間拷貝文件。但是,實際上大多數人只有一個Internet帳戶,FTP主要用於下載公共文件,例如共享軟體、各公司技術支持文件等。Internet上有成千上萬台匿名FTP主機,這些主機上存放著數不清的文件,供用戶免費拷貝。實際上,幾乎所有類型的信息,所有類型的計算機程序都可以在Internet上找到。這是Internet吸引重要原因之一。
匿名FTP使用戶有機會存取到世界上最大的信息庫,這個信息庫是日積月累起來的,並且還在不斷增長,永不關閉,涉及到幾乎所有主題。而且,這一切是免費的。
匿名FTP是Internet網上發布軟體的常用方法。Internet之所以能延續到今天,是因為人們使用通過標准協議提供標准服務的程序。像這樣的程序,有許多就是通過匿名FTP發布的,任何人都可以存取它們。
Internet中的有數目巨大的匿名FTP主機以及更多的文件,那麼到底怎樣才能知道某一特定文件位於哪個匿名FTP主機上的那個目錄中。這正是Archie伺服器所要完成的工作。Archie將自動在FTP主機中進行搜索,構造一個包含全部文件目錄信息的資料庫,使你可以直接找到所需文件的位置信息。
傳輸步驟FTP需要進行遠程文件傳輸的計算機必須安裝和運行ftp客戶程序。在windows操作系統的安裝過程中,通常都安裝了tcp/ip協議軟體,其中就包含了ftp客戶程序。但是該程序是字元界面而不是圖形界面,這就必須以命令提示符的方式進行操作,很不方便。
啟動ftp客戶程序工作的另一途徑是使用IE瀏覽器,用戶只需要在ie地址欄中輸入如下格式的url地址:ftp://[用戶名:口令@]ftp伺服器域名[:埠號](在CMD命令行下也可以用上述方法連接,通過put命令和get命令達到上傳和下載的目的,通過ls命令列出目錄,除了上述方法外還可以在cmd下輸入ftp回車,然後輸入openIP來建立一個連接,此方法還適用於linux下連接ftp伺服器)
通過IE瀏覽器啟動ftp的方法盡管可以使用,但是速度較慢,還回將密碼暴露在IE瀏覽器中而不安全。因此一般都安裝並運行專門的ftp客戶程序。
1、在本地電腦上登陸到國際互聯網。
2、搜索有文件共享主機或者個人電腦(一般有專門的FTP伺服器網站上公布的,上面有進入該主機或個人電腦的名稱,口令和路徑)。
3、當與遠程主機或者對方的個人電腦建立連接後,用對方提供的用戶名和口令登陸到該主機或對方的個人電腦、
4、在遠程主機或對方的個人電腦登陸成功後,就可以上傳你想跟別人分享的東東或者下載別人授權共享的東東(這里的東東是指能放到電腦里去又能在顯示屏上看到的東東)。
5、完成工作後關閉FTP下載軟體,切斷連接。
為了實現文件傳輸,用戶還要運行專門的文件傳輸程序,比如網際快車就有這方面的功能,其它還有很多專門的FTP傳輸軟體,FlashFxp為其中的傑出軟體。有興趣的網友可以試試其他的軟體,如LeapFTP總歸各有各的特色。
通信協議FTPTCP/IP協議中,FTP標准命令TCP埠號為21,Port方式數據埠為20。FTP協議的任務是從一台計算機將文件傳送到另一台計算機,它與這兩台計算機所處的位置、聯接的方式、甚至是是否使用相同的操作系統無關。假設兩台計算機通過ftp協議對話,並且能訪問Internet,你可以用ftp命令來傳輸文件。每種操作系統使用上有某一些細微差別,但是每種協議基本的命令結構是相同的。
FTP的傳輸有兩種方式:ASCII傳輸模式和二進制數據傳輸模式。
1、ASCII傳輸方式:假定用戶正在拷貝的文件包含的簡單ASCII碼文本,如果在遠程機器上運行的不是UNIX,當文件傳輸時ftp通常會自動地調整文件的內容以便於把文件解釋成另外那台計算機存儲文本文件的格式。但是常常有這樣的情況,用戶正在傳輸的文件包含的不是文本文件,它們可能是程序,資料庫,字處理文件或者壓縮文件(盡管字處理文件包含的大部分是文本,其中也包含有指示頁尺寸,字型檔等信息的非列印字元)。在拷貝任何非文本文件之前,用binary命令告訴ftp逐字拷貝,不要對這些文件進行處理,這也是下面要講的二進制傳輸。
2、二進制傳輸模式:在二進制傳輸中,保存文件的位序,以便原始和拷貝的是逐位一一對應的。即使目的地機器上包含位序列的文件是沒意義的。例如,macintosh以二進制方式傳送可執行文件到Windows系統,在對方系統上,此文件不能執行。如果你在ASCII方式下傳輸二進制文件,即使不需要也仍會轉譯。這會使傳輸稍微變慢,也會損壞數據,使文件變得不能用。(在大多數計算機上,ASCII方式一般假設每一字元的第一有效位無意義,因為ASCII字元組合不使用它。如果你傳輸二進制文件,所有的位都是重要的。)如果你知道這兩台機器是同樣的,則二進制方式對文本文件和數據文件都是有效的。
3、FTP的工作方式:FTP支持兩種模式,一種方式叫做Standard(也就是PORT方式,主動方式),一種是Passive(也就是PASV,被動方式)。Standard模式FTP的客戶端發送PORT命令到FTP伺服器。Passive模式FTP的客戶端發送PASV命令到FTPServer。
下面介紹一個這兩種方式的工作原理:
Port模式FTP客戶端首先和FTP伺服器的TCP21埠建立連接,通過這個通道發送命令,客戶端需要接收數據的時候在這個通道上發送PORT命令。PORT命令包含了客戶端用什麼埠接收數據。在傳送數據的時候,伺服器端通過自己的TCP20埠連接至客戶端的指定埠發送數據。FTPserver必須和客戶端建立一個新的連接用來傳送數據。
Passive模式在建立控制通道的時候和Standard模式類似,但建立連接後發送的不是Port命令,而是Pasv命令。FTP伺服器收到Pasv命令後,隨機打開一個高端埠(埠號大於1024)並且通知客戶端在這個埠上傳送數據的請求,客戶端連接FTP伺服器此埠,然後FTP伺服器將通過這個埠進行數據的傳送,這個時候FTPserver不再需要建立一個新的和客戶端之間的連接。
很多防火牆在設置的時候都是不允許接受外部發起的連接的,所以許多位於防火牆後或內網的FTP伺服器不支持PASV模式,因為客戶端無法穿過防火牆打開FTP伺服器的高端埠;而許多內網的客戶端不能用PORT模式登陸FTP伺服器,因為從伺服器的TCP20無法和內部網路的客戶端建立一個新的連接,造成無法工作。
③ 怎麼用http上傳一個文件到伺服器 python
首先,標准HTTP協議對上傳文件等表單的定義在這里:wwwietforg/rfc/rfc1867txt 大概數據包格式如下:
單文件:
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
... contents of file1.txt ...
--AaB03x--
多文件:
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"
其次,python上傳文件的幾種方法:
1 自己封裝HTTP的POST數據包:http//stackoverflowcom/questions/680305/using-multipartposthandler-to-post-form-data-with-python
import httplibimport mimetypesdef post_multipart(host, selector, fields, files): content_type, body = encode_multipart_formdata(fields, files) h = httplib.HTTP(host) h.putrequest('POST', selector) h.putheader('content-type', content_type) h.putheader('content-length', str(len(body))) h.endheaders() h.send(body) errcode, errmsg, headers = h.getreply() return h.file.read() def encode_multipart_formdata(fields, files): LIMIT = '----------lImIt_of_THE_fIle_eW_$' CRLF = '\r\n' L = [] for (key, value) in fields: L.append('--' + LIMIT) L.append('Content-Disposition: form-data; name="%s"' % key) L.append('') L.append(value) for (key, filename, value) in files: