Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
開發過程中,經常遇到中文亂碼問題,以前總是解決就好,并沒有對該問題總結一下,現在來總結一下開發過程中常見的中文亂碼問題。
一、有必要了解一些基本的編碼知識:
這篇字符編碼筆記是必讀的
jsp的三次編碼
第一階段:JVM將.jsp文件編譯為.java文件。JVM先讀取pageEncoding的值,根據該值去讀取.jsp文件,然后由指定的編碼方案生成UTF-8的.java文件。
第二階段:JVM將.java文件轉換為.class文件,從UTF-8至UTF-8。這個過程就與任何編碼的設置都沒有關系了,經過這個階段后.java文件就轉換成了統一的UTF-8編碼的.class文件了。
第三階段:服務器將處理的結果返回給瀏覽器,這個階段則依靠contentType的charset,如果設置了charset則瀏覽器就會使用指定的編碼格式進行解碼,否則采用默認的ISO-8859-1編碼格式進行解碼處理。
jsp中的編碼設置
pageEncoding:<%@ page pageEncoding=”UTF-8”%>
上文中第一階段,使用該值去讀取jsp文件,為避免中文亂碼,跟jsp文件編碼一致;對服務器響應進行重新編碼,即jsp的輸出流在瀏覽器中顯示的編碼(不是主要作用)。
contentType: <%@ page contentType=”text/html;charset=UTF-8”%>
使用該值對服務器響應進行重新編碼,即jsp的輸出流在瀏覽器中顯示的編碼;對表單get和post請求數據編碼;上文中第一階段,使用該值去讀取jsp文件(不是主要作用)。
< META http-equiv=”Content-Type” content=”text/html;charset=UTF-8”>
網頁的編碼信息 ,說明頁面制作所使用的編碼。
request.setCharacterEncoding()
可用在servlet和jsp頁面中,作用是設置對客戶端請求進行重新編碼的編碼,即post方式提交的數據進行編碼。
response.setCharacterEncoding()
與<%@ page contentType=”text/html;charset=UTF-8”%>一樣。
response.setContentType()
與<%@ page contentType=”text/html;charset=UTF-8”%>一樣。
response.setHeader(“Content-Type”,”text/html;charset=UTF-8”)
與< META http-equiv=”Content-Type” content=”text/html; charset=UTF-8”>一樣。
注意:上文1,2,3中有部分功能是一樣的,是有優先級的,在讀取jsp文件時,1>2;在對服務器響應進行編碼的時候,2>1>3,一般情況下,1,2都寫。
http請求默認以”ISO-8859-1”的編碼來傳送URL的。
二、中文亂碼的幾種情況及最簡單的解決方案:
pageEncoding設置錯誤
pageEncoding設置為jsp文件的編碼類型。
查詢字符串包含中文
中文的編碼方式取決于瀏覽器,chrome為UTF-8,IE為GB2312,這是由于瀏覽器并沒有遵循URI編碼規范。有兩種解決方法:
開發過程中,將查詢字符串提前編碼,
如:http://www.baidu.com/demo?demo=%D6%D0%B9%FA (UTF-8編碼)
在Servlet的doGet()方法中添加
1 | String value = new String(request.getParameter("parameterName").getBytes("ISO-8859-1"),"瀏覽器的編碼方式"); |
表單中的get和post數據包含中文
中文的編碼方式取決于上文的contentType中的charset,有兩種解決辦法:
在Servlet的doPost()方法中添加request.setCharacterEncoding(“charset的值”);(僅對post有用)
在Servlet的doPost()方法中添加
1 | String value = new String(request.getParameter("parameterName").getBytes("ISO-8859-1"),"charset的值"); |
三、原理
我們通過上面的方法可以解決亂碼問題,下面講講原理:
客戶端發到服務器的數據需要在客戶端進行編碼,類似于:String parameterName = "中國".getBytes("UTF-8")
然后將編碼后的數據發到服務器。
客戶端接受數據,request.getParameter(“”)的作用就是對接收到的數據進行解碼,默認使用ISO-8859-1進行解碼,可以使用request.setCharacterEncoding(“”)進行設置,但僅對post有用。假如我們使用默認的ISO-8859-1,肯定亂碼,因為編碼跟解碼不一致,那此時怎么辦呢,引出了上文中的兩種解決方案:使用request.setCharacterEncoding(“”)改變request.getParameter(“”)的解碼方式或者new String(request.getParameter("parameterName").getBytes("ISO-8859-1"),"charset的值")
將request.getParameter(“”)解碼的數據重新編碼再解碼。
四、其他
在jsp中的頁面使用response.setContentType()等設置字符集會破壞jsp容器自身的頁面編碼,會引起html中字符亂碼,腳本不會亂,所以不建議設置。在開發中多采用page指令設置字符集。
1234567891011121314151617 | <% response.setContentType("text/html;charset=UTF-8"); String str = new String("你好".getBytes("iso-8859-1"),"utf-8");%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><p>你好</p><br><%=str %></body></html> |
網頁測試
.NET6.0的MVC中,可以通過以下方式將參數傳遞給Partial View:
<partial name="_MyPartial" model='new { code=1,name="參數值" } ' />
但是這樣會出現中文亂碼問題,使用下面的方式可以解決中文亂碼問題:
<partial name="_MyPartial" model='new { code=1,name=@Html.Raw(System.Net.WebUtility.HtmlEncode("參數值")) } ' />
在上面的示例中,使用 System.Net.WebUtility.HtmlEncode 方法對參數進行編碼,然后使用 Html.Raw 方法來解碼,以確保中文字符正確顯示。
通過這種方式,可以避免在 .NET 6.0的MVC中使用 <partial> 傳遞參數時出現中文亂碼的問題。
在Partial View中獲取參數的值如下面示例代碼:
<div>
<p>@Model.code</p>
<p>@Model.name</p>
</div>
希望這個例子對您有所幫助。
面已經介紹了HttpServletResponse響應對象中的一些常用方法,這一小節介紹如何使用HttpServletResponse響應對象,解決中文亂碼問題。
使用HttpServletResponse響應對象,發送數據給瀏覽器客戶端的時候,瀏覽器接收到中文,會出現亂碼情況,出現這個問題的根本原因還是:瀏覽器和服務器之間的編碼字符集不一致。
默認情況下,Servlet容器是采用ISO-8859-1的編碼將數據發送給瀏覽器客戶端的,但是客戶端采用何種編碼方式來解析是不一定的,有可能是UTF-8、也有可能是GBK,所以這就導致編碼不一致,從而造成中文亂碼問題。
那么針對這種亂碼問題???我們要如何解決呢???解決的辦法很簡單:那就是主動告訴Servlet容器采用哪種編碼方式,并且告訴瀏覽器客戶端采用哪種方式來解碼就可以啦。
解決方案:調用response響應對象的【setContentType()】方法、或者調用【setCharacterEncoding()】方法來指定編碼即可。
// 方式一(推薦)
// 告訴Servlet容器采用UTF-8字符集進行編碼
// 并且告訴瀏覽器,采用UTF-8字符集進行解碼
response.setContentType("text/html;charset=UTF-8");
// 方式二
// 解決響應亂碼問題
// 并且告訴瀏覽器,采用UTF-8字符集進行解碼
response.setCharacterEncoding("UTF-8");
通過以上兩種方式,就可以解決返回數據的亂碼問題啦。
今天就到這里,未完待續~~
*請認真填寫需求信息,我們會在24小時內與您取得聯系。