青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

深入淺出URL編碼

版權聲明:如有轉載請求,請注明出處:http://blog.csdn.net/yzhz  楊爭  

一、問題:
       
編碼問題是JAVA初學者在web開發過程中經常會遇到問題,網上也有大量相關的文章介紹,但其中很多文章并沒有對URL中使用了中文等非ASCII的字符造成服務器后臺程序解析出現亂碼的問題作出準確的解釋和說明。本文將詳細介紹由于在URL中使用了中文等非ASCII的字符造成亂碼的問題。

1、在URL中中文字符通常出現在以下兩個地方:
(1)
Query String中的參數值,比如
http://search.china.alibaba.com/search/offer_search.htm?keywords=中國
(2)servlet path,比如http://search.china.alibaba.com/selloffer/中國.html


2、出現亂碼問題的原因主要是以下幾方面:
(1)
、瀏覽器:我們的客戶端(瀏覽器)本身并沒有遵循URI編碼的規范
http://www.w3.org/International/O-URL-code.html)。
(
2)Servlet服務器:Servlet服務器的沒有正確配置。
(3)
、開發人員并不了解Servlet的規范和API的含義。

二、基礎知識:
1
、一個http請求經過的幾個環節:
瀏覽器(ie firefox)get/post------------>Servlet服務器------------------------------->瀏覽器顯示
                              
編碼                 解碼成unicode,然后將顯示的內容編碼        解碼
(1)
瀏覽器把URL(以及post提交的內容)經過編碼后發送給服務器。
(2)
這里的Servlet服務器實際上指的是由Servlet服務器提供的servlet實現ServletRequestWrapper,不同應用服務器的servlet實現不同,這些servlet的實現把這些內容解碼轉換為unicode,處理完畢后,然后再把結果(即網頁)編碼返回給瀏覽器。
(3)
瀏覽器按照指定的編碼顯示該網頁。

        當對字符串進行編碼和解碼的時候都涉及到字符集,通常使用的字符集為ISO8859-1GBKUTF-8UNICODE


2
URL的組成:
域名:端口/contextPath/servletPath/pathInfo?queryString
說明:

1ContextPath是在Servlet服務器的配置文件中指定的。
對于weblogic
contextPath
是在應用的weblogic.xml中配置。
<context-root>/</context-root>
 
對于tomcat
contextPath
是在server.xml中配置。
<Context path="/" docBase="D:/server/blog.war" debug="5" reloadable="true" crossContext="true"/>

對于jboos
contextPath
是在應用的jboss-web.xml中配置。
<jboss-web>
    <context-root>/</context-root>
</jboss-web>

2ServletPath是在應用的web.xml中配置。
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/example/*</url-pattern>
</servlet-mapping>

2Servlet API
我們使用以下servlet API獲得URL的值及參數。
request.getParameter("name");         //
獲得queryString的參數值(來自于getpost),其值經過Servlet服務器URL Decode過的
request.getPathInfo();                //
注意:pathinfo返回的字符串是經過Servlet服務器URL Decode過的。
requestURI = request.getRequestURI(); //
內容為:contextPath/servletPath/pathinfo 瀏覽器提交過來的原始數據,未被Servlet服務器URL Decode過。


3
、開發人員必須清楚的servlet規范:
(1) HttpServletRequest.setCharacterEncoding()
方法 僅僅只適用于設置post提交的request body的編碼而不是設置get方法提交的queryString的編碼。該方法告訴應用服務器應該采用什么編碼解析post傳過來的內容。很多文章并沒有說明這一點。
(2) HttpServletRequest.getPathInfo()
返回的結果是由Servlet服務器解碼(decode)過的。
(3) HttpServletRequest.getRequestURI()
返回的字符串沒有被Servlet服務器decoded過。
(4) POST
提交的數據是作為request body的一部分。
(5)
網頁的Http頭中ContentType("text/html; charset=GBK")的作用:
   (a)
告訴瀏覽器網頁中數據是什么編碼;
   (b)
表單提交時,通常瀏覽器會根據ContentType指定的charset對表單中的數據編碼,然后發送給服務器的。
  
這里需要注意的是:這里所說的ContentType是指http頭的ContentType,而不是在網頁中meta中的ContentType


三、下面我們分別從瀏覽器和應用服務器來舉例說明:
URLhttp://localhost:8080/example/中國?name=中國
漢字   編碼      二進制表示
中國   UTF-8     0xe4 0xb8 0xad 0xe5 0x9b 0xbd[-28, -72, -83, -27, -101, -67]
中國   GBK       0xd6 0xd0 0xb9 0xfa[-42, -48, -71, -6]
中國   ISO8859-1 0x3f,0x3f[63, 63]信息失去


(
)、瀏覽器
1
GET方式提交,瀏覽器會對URL進行URL encode,然后發送給服務器。
(1)
對于中文IE,如果在高級選項中選中總以UTF-8發送(默認方式),則PathInfoURL Encode是按照UTF-8編碼,QueryString是按照GBK編碼。
http://localhost:8080/example/中國?name=中國
實際上提交是:
GET /example/%E4%B8%AD%E5%9B%BD?name=%D6%D0%B9%FA

(1) 對于中文IE,如果在高級選項中取消總以UTF-8發送,則PathInfoQueryStringURL encode按照GBK編碼。
實際上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA

(3) 對于中文firefox,則pathInfoqueryString都是URL encode按照GBK編碼。
實際上提交是:
GET /example/%D6%D0%B9%FA?name=%D6%D0%B9%FA

很顯然,不同的瀏覽器以及同一瀏覽器的不同設置,會影響最終URLPathInfo的編碼。對于中文的IEFIREFOX都是采用GBK編碼QueryString

小結:解決方案:
1
URL中如果含有中文等非ASCII字符,則瀏覽器會對它們進行URLEncode。為了避免瀏覽器采用了我們不希望的編碼,所以最好不要在URL中直接使用非ASCII字符,而采用URL Encode編碼過的字符串%.
比如:
URLhttp://localhost:8080/example/中國?name=中國
建議:
URL
http://localhost:8080/example/%D6%D0%B9%FA?name=%D6%D0%B9%FA

2、我們建議URLPathInfoQueryString采用相同的編碼,這樣對服務器端處理的時候會更加簡單。

2、還有一個問題,我發現很多程序員并不明白URL Encode是需要指定字符集的。不明白的人可以看看這篇文檔:http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/net/URLEncoder.html

2 POST提交
       
對于POST方式,表單中的參數值對是通過request body發送給服務器,此時瀏覽器會根據網頁的ContentType("text/html; charset=GBK")中指定的編碼進行對表單中的數據進行編碼,然后發給服務器。
在服務器端的程序中我們可以通過Request.setCharacterEncoding() 設置編碼,然后通過request.getParameter獲得正確的數據。

解決方案:
1
、從最簡單,所需代價最小來看,我們對URL以及網頁中的編碼使用統一的編碼對我們來說是比較合適的。
如果不使用統一編碼的話,我們就需要在程序中做一些編碼轉換的事情。這也是我們為什么看到有網絡上大量的資料介紹如何對亂碼進行處理,其中很多解決方案都只是一時的權宜之計,沒有從根本上解決問題。


(
)Servlet服務器
        Servlet
服務器實現的Servlet遇到URLPOST提交的數據中含有%的字符串,它會按照指定的字符集解碼。下面兩個Servlet方法返回的結果都是經過解碼的:
request.getParameter("name");
request.getPathInfo();

這里所說的"指定的字符集"是在應用服務器的配置文件中配置。

(1) tomcat服務器
對于tomcat服務器,該文件是server.xml
<Connector port="8080" protocol="HTTP/1.1"
               maxThreads="150" connectionTimeout="20000"
               redirectPort="8443" URIEncoding="GBK"/>
URIEncoding
告訴服務器servlet解碼URL時采用的編碼。

<Connector port="8080" ... useBodyEncodingForURI="true" />
useBodyEncodingForURI
告訴服務器解碼URL時候需要采用request body指定的編碼。

(2) weblogic服務器
對于weblogic服務器,該文件是weblogic.xml
<input-charset>
  <java-charset-name>GBK</java-charset-name>
</input-charset>

()瀏覽器顯示
       
瀏覽器根據http頭中的ContentType("text/html; charset=GBK"),指定的字符集來解碼服務器發送過來的字節流。我們可以調用HttpServletResponse.setContentType()設置http頭的ContentType

總結:
1
URL中的PathInfoQueryString字符串的編碼和解碼是由瀏覽器和應用服務器的配置決定的,我們的程序不能設置,不要期望用request.setCharacterEncoding()方法能設置URL中參數值解碼時的字符集。
所以我們建議URL中不要使用中文等非ASCII字符,如果含有非ASCII字符的話要使用URLEncode編碼一下,比如:
http://localhost:8080/example1/example/中國
正確的寫法:
http://localhost:8080/example1/example/%E4%B8%AD%E5%9B%BD
并且我們建議URL中不要在PathInfoQueryString同時使用非ASCII字符,比如
http://localhost:8080/example1/example/
中國?name=中國
原因很簡單:不同瀏覽器對URLPathInfoQueryString編碼時采用的字符集不同,但應用服務器對URL通常會采用相同的字符集來解碼。

2、我們建議URL中的URL Encode編碼的字符集和網頁的contentType的字符集采用相同的字符集,這樣程序的實現就很簡單,不用做復雜的編碼轉換。

發表于 @ 2007年07月03 15:14:00 | 評論( 18 ) | 編輯| 舉報| 收藏

pwlazy 發表于200775 15:42:21  IP:舉報

有個疑問?
原文1
(b)
表單提交時,通常瀏覽器會根據ContentType指定的charset對表單中的數據編碼,然后發送給服務器的。
原文2
很顯然,不同的瀏覽器以及同一瀏覽器的不同設置,會影響最終URLPathInfo的編碼。對于中文的IEFIREFOX都是采用GBK編碼QueryString

那么瀏覽器提交的時候到底按哪個標準編碼?
難道原文1處指的是post?原文2處指的是get?

yzhzclip_image001 發表于200775 15:50:47  IP:舉報

是的,原文1是指post的方式,因為get方式的時候用戶只輸入url,瀏覽器沒有什么編碼可參考,所以get方式的時候瀏覽器采用自己的規定去編碼url

對于post方式,由于服務器先前已返回了網頁給瀏覽器,所以post的時候瀏覽器會根據網頁的contenttype來編碼表單的數據。

pwlazy 發表于200775 15:56:33  IP:舉報

如果提交的數據中不含%,服務器又該如何解碼

yzhzclip_image001 發表于200775 16:31:40  IP:舉報

呵呵,你可以看看java.net.URLDecoderdecode方法是怎么做的?它按照字符集,該怎么做就怎么做。
package java.net;
public class URLDecoder {
public static String decode(String s, String enc)
throws UnsupportedEncodingException{

boolean needToChange = false;
int numChars = s.length();
StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
int i = 0;

if (enc.length() == 0) {
throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
}

char c;
byte[] bytes = null;
while (i < numChars) {
c = s.charAt(i);
switch (c) {
case '+':
sb.append(' ');
i++;
needToChange = true;
break;
case '%':
/*
* Starting with this instance of %, process all
* consecutive substrings of the form %xy. Each
* substring %xy will yield a byte. Convert all
* consecutive bytes obtained this way to whatever
* character(s) they represent in the provided
* encoding.
*/

try {

// (numChars-i)/3 is an upper bound for the number
// of remaining bytes
if (bytes == null)
bytes = new byte[(numChars-i)/3];
int pos = 0;

while ( ((i+2) < numChars) &&
(c=='%')) {
bytes[pos++] =
(byte)Integer.parseInt(s.substring(i+1,i+3),16);<

pwlazy 發表于200775 17:17:54  IP:舉報

你給我的這段代碼實際上已經假定傳入了編碼即enc,否則會拋意外
我想問的其實是如果不通過瀏覽器請求,通過應用程序或者腳本請求某個url,而且這個url并未顯式的編碼,那最終發送的服務器的url的編碼情況是怎樣的

yzhzclip_image001 發表于200775 17:28:39  IP:舉報

那服務器會通過默認的編碼解析URL

當存在這種情況的話,我們通常的做法是雙方約定好url采用的編碼,這樣服務器端的servlet根據約定好的編碼去解析url

pwlazy 發表于200775 17:38:25  IP:舉報

比如我在程序中發送請求http://xxx.com?y=中國,到服務器的時候
"
中國"兩個字編碼情況是怎樣(此時服務器還沒開始解碼)

yzhzclip_image001 發表于200775 17:56:26  IP:舉報

舉個例子:
如果你采用httpClient來發送這個url的話,httpclient會把這個url encode,然后發送給服務器。這時候encode采用的字符集為httpclient默認的字符集。

所以我建議如果你的url帶有中文等非ascii字符的話,你最好自己先encode,這樣httpclient encode的時候就不會對這些字符進行改變,這樣你就控制url的編碼,比如我采用gbk,那么我發送的url就是:

String url = http://xxx.com?y=%D6%D0%B9%FA
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);

yzhzclip_image001 發表于200775 17:58:58  IP:舉報

接上面:
那么服務器端按照gbk解碼就可以了。
所以一句話,采用get方式最重要的是發送方和接收方都約定好編碼。

pwlazy 發表于200776 10:56:19  IP:舉報

謝謝你的回答
另外一個問題:
我一個應用全部使用utf-8 編碼,頁面metaurlencode,數據庫,服務器tomcat使用默認編碼iso- 8859-1

使用post提交中文的時候,無須轉碼OK
但采用get+urlencode的時候必須后臺轉碼iso-8859-1---utf-8

這個原因是什么?按照你上面說的,我頁面的metautf-8,那么form提交應該是utf-8編碼,那么應該和get+urlencode效果一樣,但到服務器端的時候,前者需要轉碼后者不需要,難道服務器只對get解碼而不理會post

yzhzclip_image001 發表于200776 11:13:31  IP:舉報

沒看明白,你現在是get方式提交是好的,還是post方式提交是好的。

有幾個問題,你要告訴我。
1
、在tomcat的配置中URIEncodinguseBodyEncodingForURI的值是多少,你的tomcat版本是多少?
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" URIEncoding="GBK" useBodyEncodingForURI="true"/>
2
、頁面meta寫明是編碼有時候是沒有用的,關鍵是你的http頭中的編碼是什么,就是HttpServletResponse.setContentType()設置http頭的ContentType的編碼是什么?

pwlazy 發表于200776 11:28:24  IP:舉報

我現在post提交沒問題
get+urlencode
也沒問題,但是需要在后臺轉一下碼(iso-8859-1---utf-8

我沒弄明白為什么后者需要轉碼,前者不需要
你有msn嗎? 我的pwlazy@sina.com

yzhzclip_image001 發表于200776 15:50:22  IP:舉報

yangzheng027@hotmail.com

xyf197879 發表于20071113 16:58:21  IP:舉報

如果我在IE7中直接輸入"http://localhost:8080/example1/example/中國?name=中國",是怎樣處理的?

mlz_2 發表于200857 12:36:27  IP:舉報

謝謝,
我遇到了類似的問題,當post的時候,中文不會亂碼;而使用GET的時候,中文就會亂碼

我使用的是UTF-8的編碼,使用get方式,在接收端發現中文被轉換成gb2312

讀完此文,大概知道了原因,也就不在嘗試其他解決辦法了,而是直接使用post方式,就不會轉碼了。

sfdev 發表于2009120 20:43:04  IP:舉報

好文,不過文檔里面有些測試結果應該是有前置條件的,比如queryString為什么用GBK編碼、可能會用其他字符集來編碼嗎?
我在本文的基礎上我進一步整理了下,具體見《中文化和國際化問題權威解析之五:URL編碼/Misc》;
http://blog.csdn.net/sfdev/archive/2009/01/20/3841719.aspx

sfdev 發表于2009120 20:43:42  IP:舉報

好文,不過文檔里面有些測試結果應該是有前置條件的,比如queryString為什么用GBK編碼、可能會用其他字符集來編碼嗎?
我在本文的基礎上我進一步整理了下,具體見《中文化和國際化問題權威解析之五:URL編碼/Misc》;
http://blog.csdn.net/sfdev/archive/2009/01/20/3841719.aspx

swit1983 發表于200986 14:35:58  IP:舉報

我在jspcharset=gbk)里面用ajax 的時候querystring中用js的函數URIencode() 服務器用URIdecode可以,但是用window.location.href=...../?area=德清用上面同樣的方法怎么不行啊?

 

posted on 2009-09-08 18:33 肥仔 閱讀(4935) 評論(0)  編輯 收藏 引用 所屬分類: HTTP & URL

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一区二区日韩免费看| 亚洲欧美日韩直播| 欧美激情女人20p| 久久深夜福利免费观看| 久久久免费精品| 久久精品国产v日韩v亚洲| 久久激情中文| 欧美成人精品高清在线播放| 欧美第十八页| 欧美日韩成人在线视频| 欧美日韩午夜在线视频| 国产精品久久久久久久久久久久久久| 欧美精品国产精品日韩精品| 欧美日韩大片| 国产日韩欧美精品综合| 亚洲大片一区二区三区| 99日韩精品| 亚洲欧美在线观看| 美女网站久久| 日韩一级免费观看| 亚洲欧美在线播放| 久久综合色天天久久综合图片| 欧美成人亚洲成人日韩成人| 欧美日韩高清在线观看| 国产午夜精品视频| 亚洲美女电影在线| 免费亚洲网站| 国产精品一二| 亚洲精品视频免费| 久久国产福利国产秒拍| 亚洲国产日韩欧美综合久久| 亚洲乱码视频| 久久这里有精品视频| 国产精品久久久久久久久免费| 影音国产精品| 午夜精品偷拍| 亚洲精品久久久久久久久久久久久| 亚洲欧美在线aaa| 欧美大片免费久久精品三p| 国产精品日韩专区| 99精品欧美一区二区三区综合在线| 午夜精品久久久久久久久久久久久 | 欧美影院在线播放| 欧美成年人视频| 亚洲欧美日韩精品久久久久| 欧美经典一区二区| 在线高清一区| 久久久久久久久久久久久女国产乱 | 国产精品美女久久久久av超清| 亚洲成人资源| 久久综合中文色婷婷| 亚洲欧美视频在线观看| 欧美日韩一区二区高清| 亚洲精品自在在线观看| 蜜臀av一级做a爰片久久| 欧美亚洲系列| 国产精品丝袜久久久久久app| 亚洲乱码国产乱码精品精天堂| 看欧美日韩国产| 欧美一级一区| 国产欧美一区二区三区另类精品 | 99国产麻豆精品| 欧美激情国产高清| 亚洲欧洲另类| 亚洲精品乱码久久久久久久久| 麻豆精品视频在线观看| 在线观看国产欧美| 免费观看国产成人| 久久只精品国产| 亚洲成色www8888| 欧美国产日本高清在线| 久久国产精品亚洲77777| 国产欧美一级| 久久久久久久一区| 久久久久久久激情视频| 伊人成综合网伊人222| 美女视频黄免费的久久| 免费在线观看成人av| 日韩一级在线| 亚洲自拍高清| 国外成人在线| 亚洲韩国青草视频| 欧美午夜激情视频| 久久精品一二三| 蜜月aⅴ免费一区二区三区| 99国产一区| 亚洲欧美日韩在线观看a三区| 国产专区精品视频| 亚洲第一天堂av| 欧美人与性动交cc0o| 亚洲欧美日韩精品一区二区| 欧美自拍丝袜亚洲| 亚洲免费成人av电影| 一本大道久久a久久精品综合| 国产女人精品视频| 欧美成年人视频| 国产精品久久久久9999吃药| 久久亚洲风情| 欧美日韩日本国产亚洲在线| 久久精品99无色码中文字幕| 麻豆成人综合网| 午夜天堂精品久久久久| 久久久亚洲国产天美传媒修理工| 日韩午夜电影| 久久精品二区亚洲w码| 夜夜爽99久久国产综合精品女不卡| 一区二区久久久久| 影音先锋亚洲精品| 一区二区三区 在线观看视频| 国产一区二区三区在线观看免费| 欧美成人精品一区二区| 国产精品视频xxx| 最近中文字幕日韩精品| 国内视频一区| 亚洲免费在线观看视频| 一本一本大道香蕉久在线精品| 欧美在线日韩精品| 亚洲欧美视频一区| 欧美日韩成人综合在线一区二区 | 亚洲精品麻豆| 国内精品视频久久| 亚洲精品专区| 亚洲精品永久免费| 久久这里只有| 久久天天躁狠狠躁夜夜爽蜜月| 欧美午夜精品久久久久久浪潮| 欧美国产三区| 影音先锋中文字幕一区| 欧美一区二区女人| 欧美影院久久久| 国产精品一区二区三区久久| 亚洲最新合集| 国产精品视频xxxx| 亚洲最新合集| 欧美成人精品1314www| 另类欧美日韩国产在线| 国产日韩欧美不卡在线| 亚洲免费中文| 久久国产精品99精品国产| 欧美日韩在线播放三区| 91久久精品一区二区三区| 亚洲黄色三级| 欧美日本韩国一区| 亚洲国产另类久久久精品极度| 亚洲精品久久久久久一区二区| 老司机aⅴ在线精品导航| 久久手机精品视频| 在线免费观看一区二区三区| 亚洲欧美日韩一区二区三区在线观看| 欧美韩日高清| 亚洲激情国产精品| 亚洲高清视频一区| 久久久久久**毛片大全| 欧美本精品男人aⅴ天堂| 国产主播一区| 免费在线观看日韩欧美| 亚洲美女在线观看| 先锋影音久久久| 狠狠久久亚洲欧美| 欧美二区在线观看| 亚洲美女视频在线观看| 午夜亚洲福利在线老司机| 国产区日韩欧美| 久久一区亚洲| 亚洲精品日韩欧美| 亚洲在线免费视频| 国内精品久久久久影院 日本资源| 欧美诱惑福利视频| 亚洲国产精品激情在线观看| 亚洲图片欧美一区| 国产日韩综合| 免费视频最近日韩| 亚洲视频在线观看免费| 另类成人小视频在线| 一区二区三区蜜桃网| 国产午夜精品一区理论片飘花| 六十路精品视频| 亚洲性感美女99在线| 欧美韩国在线| 欧美在线高清视频| 亚洲精品视频在线| 国产一区二区三区最好精华液| 老鸭窝毛片一区二区三区| 一本色道久久综合亚洲精品小说| 久久精品视频免费播放| 99re热精品| 激情久久综合| 国产精品免费观看在线| 欧美成人综合网站| 久久国产乱子精品免费女| 一本一本a久久| 欧美激情视频网站| 久久久久久999| 亚洲欧美资源在线| 一本久道久久综合狠狠爱| 亚洲福利视频网| 国产一区二区福利| 国产精品一区二区三区成人| 欧美久久久久久蜜桃| 老司机免费视频一区二区三区|