瀏覽器和服務器之間如何編碼解碼

瀏覽器和服務器之間如何編碼解碼

1.瀏覽器和服務器之間編碼解碼的過程

在這裏插入圖片描述

​ 從上圖可以看出,有兩個過程是我們可以干預設置的,只有當上面兩個過程編碼格式相同的時候,纔不會出現亂碼!

2.詳細剖析get方式編碼解碼及亂碼方式

​ 對於GET方式而言:它是將數據附在URL後面進行傳輸的,這樣就很容易出現亂碼,因爲值有可能傳遞的是非ASCII嗎(HTTP協議是ASCII碼傳輸的,建立在 TCP/IP 協議之上的應用層規範)。

​ 首先瀏覽器通過指定的編碼格式將頁面編碼傳遞給服務器**(這個過程可以通過在JSP文件中的pageEncoding="")**設置。此時jsp文件轉換爲servlet文件

​ 服務器再將servlet文件解析,然後通過Unicode編碼成class文件(這個過程無法干預)。

​ 服務器將回應內容通過指定的格式編碼發送給瀏覽器,瀏覽器通過相應的解碼方式解析迴應的內容1(這個過程也是可以通過設置的Content-Type,或者response.setContentType())

contentType="text/html;charset=UTF-8"1的作用是指定對服務器響應進行重新編碼的編碼 (也就是說服務器將內容編碼響應給瀏覽器以及瀏覽器解析內容顯示都是使用這個編碼)。

pageEncoding=“UTF-8” 是將jsp編譯成servlet時的編碼

例子:

encoding.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<body>
	<form action="${pageContext.request.contextPath}/EncodingServlet" method="get">
		<input type="text" name="name">
		<input type="submit" value="提交">
	</form>
</body>

EncodingServlet

String name=request.getParameter("name");
System.out.println(name);
response.getWriter().write(response.getCharacterEncoding());
response.getWriter().write(name);

輸入:但是

結果:Console:但是

​ 頁面:ISO-8859-1 但是

結果分析:在jsp文件中contentType和pageEncoding都設置了utf-8爲什麼在頁面還是會出現亂碼而且編碼格式?

​ console輸出"但是"說明服務器是以utf-8格式編碼class文件的,而頁面輸出亂碼說明瀏覽器解析的時候並沒有按照UTF-8的格式解析服務器傳過來的內容。

打開網頁的檢查工具:

Response Header:
Content-Length: 10
Date: Wed, 20 Mar 2019 07:22:05 GMT

Request Header:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
Cookie: JSESSIONID=8DEF8C64D08009D3192C55C72AEA42A6
Host: localhost:8080
Referer: http://localhost:8080/LoginDemo/enconding.jsp
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36

發現無論是Response Header還是Request Header都沒有Content-Type的內容,這就很奇怪了,我明明在jsp文件中設置了。在這卡了很長時間,突然想到我只是在encoding.jsp文件中設置了utf-8編碼解碼格式,而我在轉到servlet的頁面並沒有設置!所以會出現在頁面中輸出ISO-8859-1 和亂碼。

證明

方案一:
<form action="${pageContext.request.contextPath}/result.jsp" method="get">
    

result.jsp    
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%=response.getCharacterEncoding()%>
</body>
</html>
  
方案二:
<form action="${pageContext.request.contextPath}/result.jsp" method="get">  
EncondingServlet
	response.setContentType("text/html;charset=UTF-8");
	String name=request.getParameter("name");
	System.out.println(name);	response.getWriter().write(response.getCharacterEncoding());

方案一:我將encoding.jsp中的form表單轉到result.jsp頁面輸出:但是 UTF-8。

方案二:在Servlet中添加了一句話:response.setContentType(“text/html;charset=UTF-8”);作用就是jsp文件中的Content-Type。輸出結果:但是 UTF-8

總結:通過上面的例子得出,只要瀏覽器與服務器之間的編碼解碼方式都設置爲UTF-8一般就不會出現亂碼問題!

​ 值得注意的是一般tomcat服務器默認解碼方式是ISO-8859-1,如果想要設置可以在conf文件夾中的server.xml的Connection標籤設置

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

​ 其實這裏設不設置無所謂,上面已經設置了setContentType(utf8)了,並且如果你只在Connection設置了UTF-8,但是在文件中沒有設置ContentType仍然會出現亂碼。

2.剖析POST方式編碼解碼及亂碼方式

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

例子:和上面的相同,method=“post”

EncodingServlet.java
//post方式解決亂碼
request.setCharacterEncoding("UTF-8");

總結:對於服務器端只需要設置

request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

​ 無論是get方式還是post方式都不會出現亂碼,但是這種方式每當你需要取值都要設置顯得很麻煩

​ 這時可以創建過濾器來解決中文亂碼問題

web.xml

<filter>
    <filter-name>EncondingFilter</filter-name>
    <filter-class>web.EncondingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>utf-8</param-value>
	</init-param>
  </filter>
  <filter-mapping>
    <filter-name>EncondingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

EncodingFilter.java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
	
		chain.doFilter(request, response);
	}

過濾器會過濾所有路徑的請求並將其編碼設置utf-8,不需要每次取值都要設置。方便很多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章