http上傳文件c
A. Java利用HttpURLConnection發送post請求上傳文件
在頁面里實現上傳文件不是什麼難事 寫個form 加上enctype = multipart/form data 在寫個接收的就可以了 沒租褲什麼難的 如果要用 HttpURLConnection來實現文件上傳 還真有點搞頭 : )
先寫個servlet把接收到的 HTTP 信息保存在一個文件中 看一下 form 表單到底封裝了什麼樣的信息
Java代碼
public void doPost(HttpServletRequest request HttpServletResponse response)
throws ServletException IOException {
//獲取輸入流 是HTTP協議中的實體內容
ServletInputStream in=request getInputStream();
//緩沖區
byte buffer[]=new byte[ ];
FileOutputStream out=new FileOutputStream( d:\test log );
int len=sis read(buffer );
//把流里的信息循環讀入到file log文件中
while( len!= ){
out write(buffer len);
len=in readLine(buffer );
}
out close();
in close();
}
來一個form表單
<form name= upform action= upload do method= POST
enctype= multipart/form data >
參數<input type= text name= username /><br/>
文件 <input type= file name= file /><br/>
文件 <input type= file name= file /><br/>
<input type= submit value= Submit />
<br />
</form>
假如我參數寫的內容是hello word 然後二個文件是二個簡單的txt文件梁譽 上傳後test log里如下
Java代碼
da e c
Content Disposition: form data; name= username
hello word
da e c
Content Disposition: form data; name= file ; filename= D:haha txt
Content Type: text/plain
haha
hahaha
da e c
Content Disposition: form data; name= file ; filename= D:huhu txt
Content Type: text/plain
messi
huhu
da e c
研究下規律發現有如下幾點特徵
第一行是 d b bc 作為分隔符 然後是 回車換行符 這個 d b bc 分隔符瀏覽器是隨機生成的
第二行是Content Disposition: form data; name= file ; filename= D:huhu txt ;name=對應input的name值 filename對應要上傳的文件名(包括路徑在內)
第三行如果是文件就有Content Type: text/plain 這里上傳的是txt文件所以是text/plain 如果上穿的是jpg圖片的話就是image/jpg了 可以自己試試看看
然後就是回弊渣簡車換行符
在下就是文件或參數的內容或值了 如 hello word
最後一行是 da e c 注意最後多了二個 ;
有了這些就可以使用HttpURLConnection來實現上傳文件功能了
Java代碼 public void upload(){
List<String> list = new ArrayList<String>(); //要上傳的文件名 如 d:haha doc 你要實現自己的業務 我這里就是一個空list
try {
String BOUNDARY = d a d c ; // 定義數據分隔線
URL url = new URL( );
HttpURLConnection conn = (HttpURLConnection) url openConnection();
// 發送POST請求必須設置如下兩行
conn setDoOutput(true);
conn setDoInput(true);
conn setUseCaches(false);
conn setRequestMethod( POST );
conn setRequestProperty( connection Keep Alive );
conn setRequestProperty( user agent Mozilla/ (patible; MSIE ; Windows NT ; SV ) );
conn setRequestProperty( Charsert UTF );
conn setRequestProperty( Content Type multipart/form data; boundary= + BOUNDARY);
OutputStream out = new DataOutputStream(conn getOutputStream());
byte[] end_data = ( + BOUNDARY + ) getBytes();// 定義最後數據分隔線
int leng = list size();
for(int i= ;i<leng;i++){
String fname = list get(i);
File file = new File(fname);
StringBuilder *** = new StringBuilder();
*** append( );
*** append(BOUNDARY);
*** append( );
*** append( Content Disposition: form data;name= file +i+ ;filename= + file getName() + );
*** append( Content Type:application/octet stream );
byte[] data = *** toString() getBytes();
out write(data);
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = ;
byte[] bufferOut = new byte[ ];
while ((bytes = in read(bufferOut)) != ) {
out write(bufferOut bytes);
}
out write( getBytes()); //多個文件時 二個文件之間加入這個
in close();
}
out write(end_data);
out flush();
out close();
// 定義BufferedReader輸入流來讀取URL的響應
BufferedReader reader = new BufferedReader(new InputStreamReader(conn getInputStream()));
String line = null;
while ((line = reader readLine()) != null) {
System out println(line);
}
} catch (Exception e) {
System out println( 發送POST請求出現異常! + e);
e printStackTrace();
}
lishixin/Article/program/Java/hx/201311/27114
B. HTTP 的 POST 參數提交和上傳的不同與 Mojolicious 的實現
對於 HTTP 協議, 我們在使用 POST 上傳的時候, 其實是有好幾種不同的處理方式的, 所以對於客戶端和伺服器端, 也分別都有不同的處理. 正常普通的網頁在提交參數上傳到伺服器的時候, 主要會根據內容的不同來使用不同的處理. 所體現在不同的地方在 Content-Type 的類型.
比如我們常常用 Mojolicious 處理這類接收到的參數和內容的時候, 會讓很多人暈掉, 所以我在這, 基於協議的頭, 來給大家介紹一下在參數和上傳的時候有什麼不同.
客戶端, 比如瀏覽器網頁中的 form 的表格的參數的不同, 客戶端比如 Linux 命令行的 curl 的參數的不同和程序介面提交參數的不同, HTTP 協議在上傳的時候, 大約會有三種不同, 這些體現在 Content-Type 的三種類型:
application/x-www-form-urlencoded
multipart/form-data
post 的 body 的內容
下面我們來詳細介紹
1. application/x-www-form-urlencoded 默認
瀏覽器: 在 HTML 中 form 有個參數是 enctype 屬性用於指定編碼方式, 常用有前面講的兩種: application/x-www-form-urlencoded 和 multipart/form-data. 但默認的時候, 我們並不指定. 不指定的時候, 默認是 "application/x-www-form-urlencoded" , 所以其實, 我們平時都是使用的這種格式來提交數據. 因為是默認就不寫出來了. 注意, 這個會對空格和特別的符號進行 url 的 encode.
程序: 我們現在以 Mojo::UserAgent 這個模塊為例子, 我們提交一個參數 args 值為 test.
$ua->post('ht tp:/ /w ww.php-oa.co m/a/b' => form => { args => 'test'});
命令:
$curl -svo /dev/null -d "args=test" htt p:/ /w ww.php-oa.co m/a/b
HTTP 協議狀態
這個時候所發送的 HTTP 的頭和內容分別如下. body 中會存著參數, 會有一個特別的 Header.
-- Blocking request (ht tp:/ /w ww.php-oa.co m/a/b)
-- Connect (ht tp:ww w.php-oa.c om:80)
-- Client >>> Server (htt p://w ww.php-oa.c om/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Connection: keep-alive
Content-Type: application/x-ww w-form-urlencoded
Accept-Encoding: gzip
Content-Length: 9
Host: www.php-oa.com
args=test
服務端接收方式
這個時候, 伺服器會根據因為是 POST 的方法, 並且頭部的 Content-Type: application/x-www-form-urlencoded 會去解析 body 的參數. 這樣在 Mojolicious 伺服器
post '/a/b' => sub {
my $self = shift;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
2. multipart/form-data 大文件, 媒體文件
對於比較大的, 有一些二進制數據和象視頻文件之類大文件, 建議使用這種方式上傳.
瀏覽器:
普通的 HTTP 的寫法如果要使用 enctype 的話, 只要象下面一樣就行.
<form action="/path/to/login" enctype="multipart/form-data">
<input disabled="disabled" name="first_name" type="text" />
<input value="Ok" type="submit" />
</form>
客戶端:
在 Mojo::UserAgent 考慮得非常周全, 當你提交的內容中包含二進制文件之類時, 就會自動幫你轉換成 "multipart/form-data" 格式提交. 這個格式會生成一個隨機字元來分割不同參數. 區分是否使用這種格式主要是, 當你提交的參數中, 又是一個引用, 並且引中可以使用 content 來指定內容或者 file 來指定路徑.
$ua->post('htt p:/ /w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { file => '/root/.bash_history' } });
# or
$ua->post('ht tp://w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { content => 'test' } });
HTTP 協議狀態
這個地方我們可以見到 Content-Type: multipart/form-data 的請求頭, 告訴文件和參數是這種格式上傳過來的.並且 boundary 用於指定一個參數之間的分割符.
-- Blocking request (ht tp://w ww.php-oa.c om/a/b)
-- Connect (ht tp:w ww.php-oa.co m:80)
-- Client >>> Server (ht p://ww w.php-oa.co m/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Type: multipart/form-data; boundary=WRoHX
Connection: keep-alive
Accept-Encoding: gzip
Content-Length: 14428
Host: www.php-oa.com
--WRoHX
Content-Disposition: form-data; name="args"
test
--WRoHX
Content-Disposition: form-data; name="args_file"; filename=".bash_history"
........文件本身
伺服器接收方式
在後端的伺服器接收的時候 Mojolicious 想得非常周到. 對於這種格式能自動解析, 並且全程非同步.不會多佔內存. 這個會自動給大的文件使用一個叫 Mojo::Upload 的對象來處理, 我們可以通過 $self->req->upload('args_file'); 這個方法取得這個內容的對象, 這個內容的對象是Mojo::Asset::File 這個對象, 存文件和取大文件之類可以直接調用.
post '/a/b' => sub {
my $self = shift;
my $upload = $self->req->upload('args_file');
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
3. POST 的 body 的內容
最後一種, 是有時我們做大文件上傳, 和提交內容之類.這個時候, 整個 body 都是文件本體. 參數象 get 一樣通過 url 傳過去.
這個就不用抓頭了, 沒任何轉換, 直接整個 body 是個大文件.
客戶端提交:
我們來看看客戶端在這個時候怎麼上傳送. 同樣, 我們使用 Mojo::UserAgent 為例子.
my $ua = Mojo::UserAgent->new;
$ua->transactor->add_generator(stream => sub {
my ($transactor, $tx, $path) = @_;
$tx->req->content->asset(Mojo::Asset::File->new(path => $path));
});
$ua->post('ht tp://w ww.php-oa.co m/a/b' => stream => '/root/.bash_history' );
伺服器接收
這個時候, 在伺服器端怎麼接收啦?
post '/a/b' => sub {
my $self = shift;
my $body = $self->req->body;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
這個, 我們直接取請求的 body 就可以了, 但這有個小問題, 這是這個文件上傳完, 這個 body 會存著所有的文件, 比如這個上傳的文件有 1G , 這個 1G 就都會占著內存. 這個情況, Mojolicious 並沒有實現事件來根據塊取文件. 晚點, 我有個有於大文件上傳的文章, 會分享我在 Mojolicious 中實現非同步以塊方式存儲文件. 這樣用戶上傳多少, 我存多少, 並不會佔用更多的內存.
好了整個三種方式都介紹完了, 大家一定注意區分哦 .
C. http中上傳文件的原理
http中上傳文件的原理如下:
在最初的http協議中,沒有上傳文件方面的功能。 rfc1867 ( http://www.ietf.org/rfc/rfc1867.txt ) 為 http 協議添加了這個功能。客戶端的瀏覽器,如 Microsoft IE, Mozila, Opera 等,按照此規范將用戶指定的文件發送到伺服器。伺服器端的網頁程序,如 php, asp, jsp 等,可以按照此規范,解析出用戶發送來的文件。Microsoft IE, Mozila, Opera 已經支持此協議,在網頁中使用一個特殊的 form 就可以發送文件。絕大部分 http server ,包括 tomcat ,已經支持此協議,可接受發送來的文件。各種網頁程序,如 php, asp, jsp 中,對於上傳文件已經做了很好的封裝。
超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網路協議。所有的WWW文件都必須遵守這個標准。設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。1960年美國人Ted Nelson構思了一種通過計算機處理文本信息的方法,並稱之為超文本(hypertext),這成為了HTTP超文本傳輸協議標准架構的發展根基。
D. 怎麼用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:
E. http文件上傳的原理是什麼請問向qq郵箱這類可以上傳文件的網頁,他們上傳文件的原理是不是,當用
有個誤區:
在上傳插件中,用戶點擊提交(確認)後,文件才開始上傳,這時候,會上傳到伺服器的某個目錄(不是臨時目錄,一般是伺服器按照管理用戶文件的規則所建立的文件夾),伺服器會返回一個指針,這個指針指向了你上傳的文件。當你發送郵件後,郵件中也會包含這個指針。不管你把這個文件放到哪個文件夾,實際上都只是存放的這個指針而已。如非管理需要,這個文件應該會永久保存,任何轉發,轉儲的行為,其實也只是操作的這個指針而不是文件本身。
即使你刪除文件,也只是在你的文件夾中刪除這個指針。所以,很多「極速秒傳」實際上是先判斷你要上傳的文件的MD5值是否已經在伺服器中存在,如果存在,就把已存在的文件的指針放上去,是不是很快?
F. 用瀏覽器上傳文件顯示http請求錯誤是怎麼回事
上傳文件顯示http請求錯誤的原因:
1、網路問題,可能當前的網路不好,可以嘗試重新上傳;或者檢查一下路由器。
2、瀏覽器的問題,可以嘗試換個瀏覽器。
3、防火牆,有可能被設置到了吧。
4、網頁問題,可能停留時間太長導致和後端的服務改帆滾器斷開連接,刷新一下。
5、文檔的格式問題。
此錯誤表明傳輸給伺服器的證書與登錄伺服器所需的證書不匹配。
請與 Web 伺服器的管理員聯系,以確認您是否具有訪問所請求資源核余的許可權。 401.2 未授權:伺服器的配置導致登錄失敗。
此錯誤表明傳輸給伺服器的證書與登錄伺服器所需的證書不匹配。此錯誤通常由未發送正確的 WWW 驗證表頭欄位所致。
請與 Web 服務轎羨器的管理員聯系,以確認您是否具有訪問所請求資源的許可權。 401.3 未授權:由於資源中的 ACL 而未授權。
此錯誤表明客戶所傳輸的證書沒有對伺服器中特定資源的訪問許可權。此資源可能是客戶機中的地址行所列出的網頁或文件,也可能是處理客戶機中的地址行所列出的文件所需伺服器上的其他文件。
請記錄試圖訪問的完整地址,並與 Web 伺服器的管理員聯系以確認您是否具有訪問所請求資源的許可權。
錯誤解釋:
此錯誤表明 Web 伺服器已經安裝了篩選程序,用以驗證連接到伺服器的用戶。此篩選程序拒絕連接到此伺服器的真品證書的訪問。 請記錄試圖訪問的完整地址,並與 Web 伺服器的管理員聯系以確認您是否具有訪問所請求資源。