表單中post與get的區別

 解決思路
   兩者的區別需要通過提交表單後才看得出來,主要是在數據發送方式和接收方式上。
具體步驟
    Post和Get都是表單屬性Method的可選值,Method的默認值爲Get,兩者的主要區別在於:
1.在客戶端,Get方式在通過URL提交數據,提交後在地址欄中的地址如圖1.4.3所示。

圖1.4.3 Get方式提交表單後的地址欄

而Post提交後地欄不變,如圖1.4.4所示。

圖1.4.4 Post方式提交表單後的地址欄不變

2.在服務器端只能用Request.QueryString來獲取Get方式提交來的數據,用Post方式提交的數據只能用Request.Form來獲取:

<%@language="VBScript" Codepage="936"%>
<html>
<head>
<title> 表單提交方式測試</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<form method="post" action="<%=Request.ServerVariables("Script_Name")%>">
  提交數據:
  <input name="oStr" type="text">
    <br>
    提交方式:
    <select name="select" οnchange="this.form.method=this.value">
      <option value="Post" selected>Post</option>
      <option value="Get">Get</option>
    </select>
    <br>
  <input type="submit" name="Submit" value="提交">
</form>
<%
 if Request("Submit")<>"" then
        Response.Write "通過"&Request.ServerVariables("Request_Method")&"方式提交的數據爲:"
    if Request.ServerVariables("Request_Method")="GET" then
          Response.Write Request.QueryString("oStr")
    else
          Response.Write Request.Form("oStr")
    end if
end if
%>
</body>
</html>

注意:雖然兩種提交方式可以統一用Request("oStr")來獲取提交數據,但是這樣對程序效率有影響,不推薦使用。
特別提示
通過IIS運行本例代碼(用http://localhost/method.asp這種方式來瀏覽,有關IIS的安裝和配置,請參考第四部分),輸入所提交的數據,選擇Post方式提交,將看到圖1.4.4所示的效果。選擇Get方式提交,效果將如圖1.4.3所示。

特別說明


一般來說,儘量避免使用Get方式提交表單,因爲有可能會導致安全問題。比如說在登陸表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。但是在分頁程序中,用Get方式就比用Post好。本例中用到的表單的屬性解釋(ASP部分請參考第四部分):
    Get把參數添加到action屬性指定的地址中,並以錨方式打開。
    Post通過HTTP post處理髮送數據。
------------------------------------------------------------------------------------------
在前面已經講過Servlet通過下面的方法來提供服務:

  實現service方法。

  實現HttpServlet的doMethod方法(doGet、doDelete、doOptions、 doPost、doPut、doTrace)。

  通常,service方法用來從客戶請求(request)中提取信息,訪問擴展資源,並基於上面的信息提供響應(response)。

  對於HTTP Servlets,正確提供響應的過程是首先填寫響應(response)的頭信息,然後從響應(response)中得到輸出流,最後向輸出流中寫入內 容信息。響應(response)頭信息必須最先設置。下面將描述如何從請求(request)中獲得信息和產生HTTP響應(response)。

  取得客戶端請求

  一個HttpServletRequest對象提供到達HTTP 頭部數據,也允許你獲取客戶端的數據。怎樣獲取這些數據取決於HTTP端請求方法。不管用任何HTTP方式,你都可以用 getParameterValues方法返回特定名稱的參數值。對於用 HTTP GET 請求的方式,這個getQueryString方法將會返回一個可以用來分析的值。

  客戶端請求(request)包含了從客戶端傳遞到Servlet的數據。所有的請求(request)都實現了ServletRequest接口。這個接口定義了一些方法訪問下面的信息,如表14-1所示。

  表14-1 ServletRequest接口方法

  ?型 描 述 對 應 方 法

  參數,用來在客戶端和Servlet之間傳送信息 getAttribute(String name)

   getAttributeNames()

   getInputStream()

   getParameter(String name)

  getParameterMap()

  getParameterNames()

  getParameterValues(String name)

  對象值屬性,用來在Servlet容器和Servlet

  之間,或者協作的Servlet之間傳遞信息 removeAttribute(String name)

   setAttribute(String name, Object o)

  有關請求使用的協議信息,

  客戶端和服務器在請求中的調用 getContentLength()

   getContentType()

   getProtocol()

  getReader()

  getRealPath(String path)

  getRemoteAddr()

  getRemoteHost()

   getRequestDispatcher(String path)

  有關請求使用的協議信息,

  客戶端和服務器在請求中的調用 getScheme()

   getServerName()

   getServerPort()

   isSecure()

  有關localization的信息 getCharacterEncoding()

   getLocale()

   getLocales()

   setCharacterEncoding(String env)

  下面的代碼段示範瞭如何使用request中的方法獲得客戶端信息。

  Enumeration params = request.getParameterNames();

  String paramName = null;

  String[] paramValues = null;

  

  while (params.hasMoreElements()) {

  paramName = (String) params.nextElement();

  paramValues = request.getParameterValues(paramName);

  System.out.println(" Parameter name is " + paramName);

  for (int i = 0; i < p> ;>

   System.out.println(", value " + i + " is " + paramValues[i].toString());

  }

  

  HTTP Servlets使用HTTP request對象(HttpServletRequest),它包含了request URL、HTTP頭信息、查詢字符串,等等。HTTP request URL 包括幾個部分:

  http://:?

  一般情況下:

  requestURI = contextPath + servletPath + pathInfo

  Context path:通過getContextPath方法獲得。

  Servlet Path:通過getServletPath方法獲得。

  PathInfo:通過getPathInfo方法獲得。

    如表14-2所示。

  表14-2 路徑的對應

  Request Path Path Elements

  /catalog/help/feedback.jsp ContextPath: /catalog ServletPath:

   /help/feedback.jsp PathInfo: null

  提供HTTP響應

  響應(response)包含了在服務器和客戶端之間傳遞的數據。所有的響應(response)都實現了ServletResponse接口。這個接口定義了一些方法提供給開發人員使用,如表14-3所示。

  表14-3 ServletResponse接口方法

  ?型 描 述 對 應 方 法

  獲得向客戶端發送數據的輸出流 發送字符流:getWriter()

   發送字節流:getOutputStream()

  指示響應返回的內容類型(例如:text/html)

  已經註冊的內容類型名稱保存在IANA

  (Internet Assigned Numbers Authority) setContentType(java.lang.String type)

  指出是否是緩衝輸出。默認情況下寫入輸出的

  內容被立即發送到客戶端。使用緩衝後寫入輸出的內容先

  不發送到客戶端,這樣Servlet有更多的時間設置相應的

  狀態碼和頭信息,或者轉移到其他的Web資源 flushBuffer()

   getBufferSize()

   isCommitted()

   reset()

   resetBuffer()

   setBufferSize(int size)

   setContentLength(int len)

  設置localization信息 getCharacterEncoding()

   getLocale()

   setLocale(java.util.Locale loc)

  HTTP response類(HttpServletResponse)有一些代表HTTP頭信息的域:

  

  狀態碼用來指出響應(response)失敗的原因。

  Cookies在客戶端存儲應用相關的信息,有時cookies用來維護和標識用戶的session。

  Servlet首先設置響應(response)頭信息,包括響應(response)的內容類別和緩衝區大小,然後在doGet方法中從響應 (response)獲得PrintWriter ,最後向輸出中寫入HTML代碼,調用close()方法提交這次對客戶端的響應(response)。示範代碼如下:

  public void doGet (HttpServletRequest request,

  HttpServletResponse response)

  throws ServletException, IOException

  

  // 設置頭信息

  response.setContentType("text/html");

  response.setBufferSize(8192);

  PrintWriter out = response.getWriter();

    

  // 向response中輸出

  out.println("" +

   "");

  ...

  out.println("");

  // 關閉輸出流

  out.close();

}

-----------------------------------------------------------------------------------------

深入研究表單提交方式:GET/POST

Hackfan

本文平臺:Windows 2000 Professional + Apache 1.3.17 + Perl 5.6.1 + Internet Explorer 5.00.2920.0000

  大家知道目前表單提交的方式有GET和POST。我在這裏不多說什麼,給大家看一個以GET方式提交的表單的請求:

GET /cgi-bin/tech/method.cgi?GET=GET HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*
Referer: http://localhost//other.html
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Host: localhost:8080
Connection: Keep-Alive

  這個請求是我們通過這個HTML代碼發出的:

<form action="http://localhost:8080/cgi-bin/tech/method.cgi" method="GET">
<input type="text" size="10" value="GET" name="GET">
<input type=submit value="GET方式">
</form>

  這個請求已經超出了我們研究的範圍,我們只研究其中的第一行。其中,第一個"GET"說出了提交的方式,是以GET方式提交的;中間的就是提交 給服務器上哪個程序,前面一部分"/cgi-bin/tech/method.cgi"就是我們HTML的form中action的內容,而後面 的"GET=GET"就是HTML的form中,input的內容:我們發現IE已經把這個表單的內容轉換成特定格式了。在Perl中,通 過$GET=$ENV{'QUERY_STRING'}獲得以GET發送的數據。

  我們再看一個以POST方式提交的表單的請求:

POST /cgi-bin/tech/method.cgi HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
powerpoint, application/vnd.ms-excel, application/msword, */*
Referer: http://localhost//other.html
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Host: localhost:8080
Content-Length: 9
Connection: Keep-Alive

POST=POST

  同樣給出HTML:

<form action="http://localhost:8080/cgi-bin/tech/method.cgi" method="POST">
<input type="text" size="10" value="POST" name="POST">
<input type=submit value="POST方式">
</form>

  我們發現其中的數據跑到了最下面。在Perl中,通過read(STDIN,$POST,$ENV{'CONTENT_LENGTH'})獲得以POST發送的數據。我記得GET發送數據最多隻能1024字節,而POST好像很大很大!

  思考:如果我有這麼一段HTML代碼,它將會出現什麼問題呢?

<form action="http://localhost:8080/cgi-bin/tech/method.cgi?GET=GET" method="POST">
<input type="text" size="10" value="POST" name="POST">
<input type=submit value="GET/POST方式">
</form>

  這個代碼在很多程序上可能用到過,但是大多數人不會好好的想一想,究竟哪些內容是以GET發送的,哪些內容是以POST發送的。我們看看它的請求是什麼:

POST /cgi-bin/tech/method.cgi?GET=GET HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
powerpoint, application/vnd.ms-excel, application/msword, */*
Referer: http://localhost//other.html
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Host: localhost:8080
Content-Length: 9
Connection: Keep-Alive

POST=POST

  哈!原來是以POST發送的。但是,你一定發現了有一部分數據放在了第一行,就是和GET的情況一樣的。其實這個例子很典型,是POST和GET混發!
  不相信你在Perl中,用read(STDIN,$POST,$ENV{'CONTENT_LENGTH'})和$GET=$ENV{'QUERY_STRING'}看看,到底哪個裏面有"GET=GET"這個數據。

  我給大家提供設備,大家自己去研究研究:

HTML部分:  

<html>
<head>
<title>Get-Post</title>
</head>

<body>
<form action="/cgi-bin/tech/method.cgi" method="GET">
<input type="text" size="10" value="GET" name="GET">
<input type=submit value="GET方式">
</form>
<form action="/cgi-bin/tech/method.cgi" method="POST">
<input type="text" size="10" value="POST" name="POST">
<input type=submit value="POST方式">
</form>
<form action="/cgi-bin/tech/method.cgi?GET=GET" method="POST">
<input type="text" size="10" value="POST" name="POST">
<input type=submit value="GET/POST方式">
</form>
<form action="/cgi-bin/tech/method.cgi?name=Hackfan&age=16&[email protected]" method="POST">
<input type="text" size="10" value="Suzhou" name="address">
<input type="text" size="10" value="msger.net" name="homepage">
<input type="text" size="10" value="106814" name="qq">
<input type=submit value="複雜GET/POST方式">
</form>
</body>
</html>

Perl部分:

#!c:/perl/bin/perl.exe

$|=1;

print "Content-type:text/html/n/n";

print "發送方式:$ENV{'REQUEST_METHOD'}<br>/n";
if(read(STDIN,$POST,$ENV{'CONTENT_LENGTH'})){
 print "POST得到的數據:$POST<br>/n";
}
if($GET=$ENV{'QUERY_STRING'}){
 print "GET得到的數據:$GET<br>/n";
}

$METHOD="POST";

for($i=0;$i<=1;$i++){
 foreach(split(/&/,$$METHOD)){
  $_=~s//+//g;
  ($name,$value)=split(/=/,$_);
  $name=~s/%([a-fA-f0-9][a-fA-f0-9])/pack("C",hex($1))/eg;
  $value=~s/%([a-fA-f0-9][a-fA-f0-9])/pack("C",hex($1))/eg;
  $$METHOD{$name}=$value;
 }
 $METHOD="GET";
}


$METHOD="POST";

for($i=0;$i<=1;$i++){
 print "Hash形式的$METHOD數據遍歷:<br>/n";
 foreach(keys %{$METHOD}){
  print "/$".$METHOD."{".$_."}=$$METHOD{$_}<br>/n";
 }
 print "<br>/n";
 $METHOD="GET";
}

exit;


####代碼結束####


  好了,我要說的是,搞這個研究究竟有什麼意義呢?
  意義是:讓你知道,用戶提交的數據哪些是用POST方式,哪些使用GET方式的!
  其實我上面那段Perl代碼已經包括了很多的技術。你通過閱讀就可以知道%GET裏面放的是用GET方式提交的,%POST同理!

  如果你對我編寫的Perl代碼感興趣,歡迎切磋:QQ:106814。至於我如何獲得IE發送來的請求的,我要說我是用Perl編的一個 Server監聽8080端口,我是不是像歐姆一樣搞研究大多東西都自己編寫(當然,讓我編寫一個操作系統就有點難度了,不過WebServer湊合)? 開玩笑呢!


QQ:106814
Email:[email protected]
Personal Page:http://www.msger.net/hackfan



發佈了3 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章