1. 程式人生 > >html url傳遞引數問題

html url傳遞引數問題

在用 ASP.Net 開發頁面的時候, 我們常常通過 System.Web.HttpUtility.UrlEncode 和 UrlDecode 在頁面間通過 URL 傳遞引數. 成對的使用 Encode 和 Decode 是沒有問題的.

但是, 我們在編寫檔案下載的頁面的時候, 常常用如下方法來指定下載的檔案的名稱:
Response.AddHeader(
"Content-Disposition","attachment; filename="+ HttpUtility.UrlEncode(fileName, Encoding.UTF8));
之所以轉換成 UTF8 是為了支援中文檔名.

這時候問題就來了, 因為 HttpUtility.UrlEncode 在 Encode 的時候, 將空格轉換成加號(
'+'), 在 Decode 的時候將加號轉為空格, 但是瀏覽器是不能理解加號為空格的, 所以如果檔名包含了空格, 在瀏覽器下載得到的檔案, 空格就變成了加號.

一個解決辦法是, 在 HttpUtility 的 UrlEncode 之後, 將 
"+" 替換成 "%20"( 如果原來是 "+" 則被轉換成 "%2b" ) , 如: 
fileName 
= HttpUtility.UrlEncode(fileName, Encoding.UTF8); 
fileName 
= fileName.Replace("+""%20"); 
不明白微軟為什麼要把空格轉換成加號而不是
"%20". 記得 JDK 的 UrlEncoder 是將空格轉換成 
"%20"的.
經檢查, 在 .Net 
2.0 也是這樣.


HttpUtility.UrlEncode 在 Encode 的時候, 將空格轉換成加號('+'), 在 Decode 的時候將加號轉為空格, 但是瀏覽器是不能理解加號為空格的, 所以如果檔名包含了空格, 在瀏覽器下載得到的檔案, 空格就變成了加號


<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>
<title>URL解碼(Decode)/編碼(Encode)</title>
</
head>
<body>
<center><font color=green size=+2>URL解碼(Decode)/編碼(Encode)</font><br>
需要解碼的字串:
<TEXTAREA ID="String1" ROWS="10" COLS="30"></TEXTAREA> 解碼後的字串:<TEXTAREA ID="String2" ROWS="10" COLS="30"></TEXTAREA><br>
需要編碼的字串:
<TEXTAREA ID="String3" ROWS="10" COLS="30"></TEXTAREA> 編碼後的字串:<TEXTAREA ID="String4" ROWS="10" COLS="30"></TEXTAREA><br>
<INPUT TYPE="button" ID="Decode" value="解碼(Decode)" onClick="javascript:String2.value=decodeURI(String1.value);">
<INPUT TYPE="button" ID="Encode" value="編碼(Encode)" onClick="javascript:String4.value=encodeURI(String3.value);">
</center>
</body>
</html> 




url傳遞中文的解決方案總結

1.設定web.config檔案。(我不喜歡設定成這樣)
<system.web>
......
<globalization requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" fileEncoding="gb2312" />
......
</system.web>
 
或者:
aspx檔案中:
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

2.傳遞中文之前,將要傳遞的中文引數進行編碼,在接收時再進行解碼。
>> 進行傳遞
string Name = "中文引數";
Response.Redirect("B.aspx?Name="+Server.UrlEncode(Name));

>> 進行接收
string Name = Request.QueryString["Name"];
Response.Write(Server.UrlDecode(Name));
或者:
 
NavigateURL='<%# "WebForm2.aspx?Singer=" + HttpUtility.UrlEncode("中國人", System.Text.Encoding.GetEncoding("GB2312")) %>'


3.如果是從 .HTML 檔案向 .Aspx 檔案進行傳遞中文引數的話(即不從後臺用 Redirect()方法進行 Url 轉換)。一樣要將傳遞的中文引數進行編碼,在接收時再進行解碼。
>> 進行傳遞
<script language="JavaScript">
function GoUrl()
{
var Name = "中文引數";
location.href = "B.aspx?Name="+escape(Name);
}
</script>
<body onclick="GoUrl()">
>> 進行接收
string Name = Request.QueryString["Name"];
Response.Write(Server.UrlDecode(Name));

一般來說。設定web.config檔案就可以了。但是如果你用 JavaScript 呼叫 webservice 方法的話(往webservice裡面傳遞中文引數)。設定 web.config 檔案好象無效。

————————————————————
在html中實現編解碼:

<script language="javascript">
function openUrl(src)
{
  var strUrl=escape(src);
  window.open(strUrl);
}
 

function change_url(src)
{
 document.location.href=escape(src);
}
 
</script> 
 
在新視窗儲存
<a href='javascript:openUrl("css/20040603123628交易中心菸葉網上集中交易系統合同.doc");' >20040603123628交易中心網上集中交易系統合同</a>
 
 
當前位置儲存,無閃爍。
<a href="#" onclick=javascript:change_url("css/20040603123628交易中心菸葉網上集中交易系統合同.doc")>20040603123628交易中心網上集中交易系統合同</a>
 
注意:路徑中的斜線是:“/”,而不是“/”,否則也不行啊。
 
 
 
 
----------------------------------------
前一陣遇到在做.net Web開發時,碰到一個很奇怪的問題,就是Url中,如果將中文字元作為引數值傳遞時,QueryString得到的值可能會出錯。簡單的說,比如下面這個Url:
UrlParmTest.aspx?parm1=中國&parm2=中國人
在Request.QueryString時,parm1和parm2得到都是"中國",顯然出現了問題,可是在某些情況下卻是正常的。

如果請求不是直接通過URL,而使用Response.Redirect在伺服器端操作,沒有遇到過類似的問題。

當時我想中文是雙位元組編碼,可能傳遞的時候就是有不確定性,還是用英文好。

可是為什麼在Server端Redirect就是正常的,問題在哪裡呢?


如果在.cs檔案中設定中文引數,請在中文引數外使用Server.UrlEncode("中文")對中文進行Encode
如果在.aspx檔案中設定,請使用<%=Server.UrlEncode("中文")%>進行Encode
在QueryString時,不用再進行Decode,可以獲得正常的中文字串

下面是給出的一些解釋:
UrlEncode把一些多位元組字元轉換成url裡允許的單位元組字元,本來瀏覽器就會自動做的,但是目前確實存在一些問題,所以自己再Encode一下,在接受端會自動對Url進行Decode。

我想Response.Redirect可能可以確保作Encode的工作,所以沒有問題。

 JavaScript Base64編碼和解碼,實現URL引數傳遞

為什麼需要對引數進行編碼?相信有過開發的經驗的廣大程式設計師都知道,在Web中,若是直接在Url地址上傳遞引數值,若是中文,或者+等什麼的就會出現亂碼現象,若是數字或者英文的好象沒有什麼問題,簡言之,傳遞過來的引數是需要進行編碼的。
在這裡,也許有人會說,為什麼不直接用Server.UrlDecode和Server.UrlEncode這兩個來進行編碼和解碼的操作呢?

的確,這兩個伺服器端物件很好使用,用起來也很方便,但是,若在客戶端是HTML的Input,查詢的時候頁面是HTML或者其他的,反正不是.NET的,那這個物件還可以用嗎?


我現在就遇到這樣的問題,查詢的東東放在頁面,而且那個頁面我根本不想讓他是.aspx結尾的,哈,感覺HTML的挺不錯,而且裡面的控制元件也是用HTML物件的。

下面先來看兩個函式,UTF16轉UTF8和UTF8轉Utf16的。
function utf16to8(str) 
{
    var 
out, i, len, c;

    
out="";
    len 
= str.length;
    
for(i =0; i < len; i++{
 c 
= str.charCodeAt(i);
 
if ((c >=0x0001&& (c <=0x007F)) {
     
out+= str.charAt(i);
 }
elseif (c >0x07FF{
     
out+= String.fromCharCode(0xE0| ((c >>12&0x0F));
     
out+= String.fromCharCode(0x80| ((c >>6&0x3F));
     
out+= String.fromCharCode(0x80| ((c >>0&0x3F));
 }
else{
     
out+= String.fromCharCode(0xC0| ((c >>6&0x1F));
     
out+= String.fromCharCode(0x80| ((c >>0&0x3F));
 }

    }

    
returnout;
}


function utf8to16(str) 
{
    var 
out, i, len, c;
    var char2, char3;

    
out="";
    len 
= str.length;
    i 
=0;
    
while(i < len) {
 c 
= str.charCodeAt(i++);
 
switch(c >>4)
 

   
case0case1case2case3case4case5case6case7:
     
// 0xxxxxxx
out+= str.charAt(i-1);
     
break;
   
case12case13:
     
// 110x xxxx   10xx xxxx
     char2 = str.charCodeAt(i++);
     
out+= String.fromCharCode(((c &0x1F<<6| (char2 &0x3F));
     
break;
   
case14:
     
// 1110 xxxx  10xx xxxx  10xx xxxx
     char2 = str.charCodeAt(i++);
     char3 
= str.charCodeAt(i++);
     
out+= String.fromCharCode(((c &0x0F<<12|
        ((char2 
&0x3F<<6|
        ((char3 
&0x3F<<0));
     
break;
 }

    }


    
returnout;
}


那麼為什麼需要進行轉化呢?因為在JavaScript中獲得的中文字元是用UTF16進行編碼的,和我們統一的頁面標準格式UTF
-8可不一樣哦,所以需要先進行轉化,上面的函式UTF-16到UTF8,然後再進行Base64的編碼。

下面是關於Js進行Base64編碼和解碼的相關操作:

var base64EncodeChars 
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars 
=new Array(
    
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1,
    
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1,
    
-1-1-1-1-1-1-1-1-1-1-162-1-1-163,
    
52535455565758596061-1-1-1-1-1-1,
    
-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  91011121314,
    
1516171819202122232425-1-1-1-1-1,
    
-1262728293031323334353637383940,
    
4142434445464748495051-1-1-1-1-1);
//客戶端Base64編碼
function base64encode(str) {
    var 
out, i, len;
    var c1, c2, c3;

    len 
= str.length;
    i 
=0;
    
out="";
    
while(i < len) {
 c1 
= str.charCodeAt(i++&0xff;
 
if(i == len)
 
{
     
out+= base64EncodeChars.charAt(c1 >>2);
     
out+= base64EncodeChars.charAt((c1 &0x3<<4);
     
out+="==";
     
break;
 }

 c2