如何利用表單傳送數據給伺服器
『壹』 如何製作簡單的表單,如何提交數據
一、表單概述
表單,在網頁中的作用不可小視,主要負責數據採集的功能,比如你可以採集訪問者的名字和e-mail地址、調查表、留言簿等等。
1、表單的組成
一個表單有三個基本組成部分: 表單標簽:這裡麵包含了處理表單數據所用CGI程序的URL以及數據提交到伺服器的方法。 表單域:包含了文本框、密碼框、隱藏域、多行文本框、復選框、單選框、下拉選擇框和文件上傳框螞滾等。 表單按鈕:包括提交按鈕、復位旦畢按鈕和一般按鈕;用於將數據傳送到伺服器上的CGI腳本或者取消輸入,還可以用表單按鈕來控制其他定義了處理腳本的處理工作。 為了顧及不同的網頁設計工具,本文只講述代碼的設計,不具體講述操作方法,下面就是表單的HTML代碼設計要點:
1.1 表單標簽<form><悶遲余/form>
『貳』 如何使用multipart/form-data格式上傳文件
在網路編程過程中需要向伺服器上傳文件。Multipart/form-data是上傳文件的一種方式。
Multipart/form-data其實就是瀏覽器用表單上傳文件的方式。最常見的情境是:在寫郵件時,向郵件後添加附件,附件通常使用表單添加,也就是用multipart/form-data格式上傳到伺服器。
表單形式上傳附件
具體的步驟是怎樣的呢?
首先,客戶端和伺服器建立連接(TCP協議)。
第二,客戶端可以向伺服器端發送數據。因為上傳文件實質上也是向伺服器端發送請求。
第三,客戶端按照符合「multipart/form-data」的格式向伺服器端發送數據。
既然Multipart/form-data格式就是瀏覽器用表單提交數據的格式,我們就來看看文件經過瀏覽器編碼後是什麼樣子。
這行指出這個請求是「multipart/form-data」格式的,且「boundary」是 「---------------------------7db15a14291cce」這個字元串。
不難想像,「boundary」是用來隔開表單中不同部分數據的。例子中的表單就有 2 部分數據,用「boundary」隔開。「boundary」一般由系統隨機產生,但也可以簡單的用「-------------」來代替。
實際上,每部分數據的開頭都是由"--" + boundary開始,而不是由 boundary 開始。仔細看才能發現下面的開頭這段字元串實際上要比 boundary 多了個 「--」
緊接著 boundary 的是該部分數據的描述。
接下來才是數據。
「GIF」gif格式圖片的文件頭,可見,unknow1.gif確實是gif格式圖片。
在請求的最後,則是 "--" + boundary + "--" 表明表單的結束。
需要注意的是,在html協議中,用 「 」 換行,而不是 「 」。
下面的代碼片斷演示如何構造multipart/form-data格式數據,並上傳圖片到伺服器。
//---------------------------------------
// this is the demo code of using multipart/form-data to upload text and photos.
// -use WinInet APIs.
//
//
// connection handlers.
//
HRESULT hr;
HINTERNET m_hOpen;
HINTERNET m_hConnect;
HINTERNET m_hRequest;
//
// make connection.
//
...
//
// form the content.
//
std::wstring strBoundary = std::wstring(L"------------------");
std::wstring wstrHeader(L"Content-Type: multipart/form-data, boundary=");
wstrHeader += strBoundary;
HttpAddRequestHeaders(m_hRequest, wstrHeader.c_str(), DWORD(wstrHeader.size()), HTTP_ADDREQ_FLAG_ADD);
//
// "std::wstring strPhotoPath" is the name of photo to upload.
//
//
// uploaded photo form-part begin.
//
std::wstring strMultipartFirst(L"--");
strMultipartFirst += strBoundary;
strMultipartFirst += L" Content-Disposition: form-data; name="pic"; filename=";
strMultipartFirst += L""" + strPhotoPath + L""";
strMultipartFirst += L" Content-Type: image/jpeg ";
//
// "std::wstring strTextContent" is the text to uploaded.
//
//
// uploaded text form-part begin.
//
std::wstring strMultipartInter(L" --");
strMultipartInter += strBoundary;
strMultipartInter += L" Content-Disposition: form-data; name="status" ";
std::wstring wstrPostDataUrlEncode(CEncodeTool::Encode_Url(strTextContent));
// add text content to send.
strMultipartInter += wstrPostDataUrlEncode;
std::wstring strMultipartEnd(L" --");
strMultipartEnd += strBoundary;
strMultipartEnd += L"-- ";
//
// open photo file.
//
// ws2s(std::wstring)
// -transform "strPhotopath" from unicode to ansi.
std::ifstream *pstdofsPicInput = new std::ifstream;
pstdofsPicInput->open((ws2s(strPhotoPath)).c_str(), std::ios::binary|std::ios::in);
pstdofsPicInput->seekg(0, std::ios::end);
int nFileSize = pstdofsPicInput->tellg();
if(nPicFileLen == 0)
{
return E_ACCESSDENIED;
}
char *pchPicFileBuf = NULL;
try
{
pchPicFileBuf = new char[nPicFileLen];
}
catch(std::bad_alloc)
{
hr = E_FAIL;
}
if(FAILED(hr))
{
return hr;
}
pstdofsPicInput->seekg(0, std::ios::beg);
pstdofsPicInput->read(pchPicFileBuf, nPicFileLen);
if(pstdofsPicInput->bad())
{
pstdofsPicInput->close();
hr = E_FAIL;
}
delete pstdofsPicInput;
if(FAILED(hr))
{
return hr;
}
// Calculate the length of data to send.
std::string straMultipartFirst = CEncodeTool::ws2s(strMultipartFirst);
std::string straMultipartInter = CEncodeTool::ws2s(strMultipartInter);
std::string straMultipartEnd = CEncodeTool::ws2s(strMultipartEnd);
int cSendBufLen = straMultipartFirst.size() + nPicFileLen + straMultipartInter.size() + straMultipartEnd.size();
// Allocate the buffer to temporary store the data to send.
PCHAR pchSendBuf = new CHAR[cSendBufLen];
memcpy(pchSendBuf, straMultipartFirst.c_str(), straMultipartFirst.size());
memcpy(pchSendBuf + straMultipartFirst.size(), (const char *)pchPicFileBuf, nPicFileLen);
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen, straMultipartInter.c_str(), straMultipartInter.size());
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen + straMultipartInter.size(), straMultipartEnd.c_str(), straMultipartEnd.size());
//
// send the request data.
//
HttpSendRequest(m_hRequest, NULL, 0, (LPVOID)pchSendBuf, cSendBufLen)
『叄』 android客戶端如何提交表單數據給web伺服器
1.伺服器端的准備
為了完成該實例,我們需要在伺服器端做以下准備工作:
(1)我們需要在MyEclipse中創建一個Web工程,用來模擬伺服器端的Web服務,這里,我將該工程命名為了「myhttp」。
(2)修改該工程的「index.jsp」文件,添加兩個輸入框和一個提交按鈕,作為該Web工程的顯示頁面。運行Tomcat,在瀏覽器中訪問該Web工程,可以看到如圖1所示的界面。
Web工程的顯示頁面
(3)在該Web工程中,創建一個繼承自HttpServlet的LoginAction類,並實現其中的doPost()方法,用來響應圖1所示頁面的用戶操作。具體實現如下:
由上述代碼可以看出,當我們在圖1所示的頁面輸入用戶名「admin」,密碼「123」時,點擊提交按鈕,會得到「Login succeeded!」的提示信息,如圖2所示。若用戶名、密碼錯誤,則會得到「Login failed!」的提示信息。
2.客戶端實現
在Android客戶端,我們需要完成的工作是:以POST方式發送用戶名密碼到上述伺服器,並獲得伺服器的驗證信息。
我們分以下幾個步驟來完成。
2.1 UI界面
在Android工程中,我們需要完成一個簡單的UI界面,用來完成用戶名密碼的輸入、發送POST請求、顯示伺服器的驗證結果,完成後的界面如圖3所示。
在MainActivity中,我們需要獲取兩個EditText控制項的輸入,「提交」按鍵的監聽,以及伺服器驗證結果的TextView內容顯示。具體實現代碼如下:
2.2發送POST請求到伺服器
可以看到上述代碼中,我們調用了HttpUtils類的靜態方法submitPostData()完成了發送POST請求到伺服器,並將該方法的返回值(伺服器的響應結果)顯示在了TextView控制項中。
通過以上的代碼可以看出,在該方法中,其實完成了3件事:
(1)將用戶名密碼封裝成請求體,這是通過調用getRequestData()方法來實現的(後面會講到這個方法的具體實現)。
(2)設置HttpURLConnection對象的各種參數(其實是設置HTTP協議請求體的各項參數),然後通過httpURLConnection.getOutputStream()方法獲得伺服器輸出流outputStream,再使用outputStream.write()方法將請求體內容發送給伺服器。
(3)判斷伺服器的響應碼,通過httpURLConnection.getInputStream()方法獲得伺服器的響應輸入流,然後再調用dealResponseResult()方法處理伺服器的響應結果。
2.3封裝請求體
使用POST請求時,POST的參數不是放在URL字元串里,而是放在HTTP請求數據中,所以我們需要對POST的參數進行封裝。
針對該實例而言,我們發送的URL請求是:http://192.168.1.101:8080/myhttp/servlet/LoginAction,但是我們需要將POST的參數(也就是username和password)封裝到該請求中,形成如下的形式:
2.4處理響應結果
最後,我們再來看一看對伺服器返回結果的處理是怎樣的。因為在本實例中,伺服器的返回結果是字元串「Login succeeded!」或「Login failed!」,所以這里我們需要做的就是將伺服器的返回結果輸入流轉化成字元串。當然了,如果伺服器返回的是圖片,那麼,我們就需要就得到的輸入流轉化成Bitmap圖片了。如下代碼是上面代碼中用到的dealResponseResult()方法的具體實現。
2.5運行效果
『肆』 一個前端提交表單到另一個前端怎麼操作
提交表單到另一個前端需要先了解兩個前端之間的通信方式。一般來說,前端之間的通信可以通過以下幾種方式實現:
1. 使用伺服器端作為中介,通過HTTP請求或WebSocket進行通信。這種方式需要在伺服器端建立介面,前端通過發送請求到伺服器端來實現與另一個前端的通信。困念
2. 使用localStorage或sessionStorage進行數據共享。這種方式可以將數據存儲在本地瀏覽器中,從而實現前端之間的數據共享。
3. 使用WebRTC進行通信。這種方式可以直接在瀏覽器之間建立點對點的連接,實現前端之間的實時通信。
具體到提交表單的操作,如果是通過伺服器端作為中介進喚段行通信,可通過form表單的action屬性指定伺服器端介面的地址,通過method屬性指汪鏈困定請求類型,以及通過表單元素的name屬性來定義需要提交的數據。如果是通過localStorage或sessionStorage進行數據共享,可通過JavaScript代碼獲取表單數據,並將其存儲到localStorage或sessionStorage中,另一個前端通過讀取localStorage或sessionStorage中的數據來獲取表單數據。如果是通過WebRTC進行通信,需要結合WebRTC的API實現表單數據的傳輸。