<kbd id="9plqc"><label id="9plqc"></label></kbd>

        <th id="9plqc"></th>
        1. <center id="9plqc"><video id="9plqc"></video></center>
          <sub id="9plqc"><form id="9plqc"><pre id="9plqc"></pre></form></sub>
          <nav id="9plqc"><form id="9plqc"><legend id="9plqc"></legend></form></nav>
          Web開發(fā)中的中文亂碼問(wèn)題 您所在的位置:網(wǎng)站首頁(yè) 偏財(cái)會(huì)偏印 Web開發(fā)中的中文亂碼問(wèn)題

          Web開發(fā)中的中文亂碼問(wèn)題

          2023-10-08 15:27| 來(lái)源: 網(wǎng)絡(luò)整理| 查看: 265

          主要內(nèi)容 1. 字符編碼理論簡(jiǎn)述 1.1 ASCII 1.2 ISO8859-1 1.3 Unicode 1.4 GBK 2. 可能發(fā)生的中文亂碼 2.1 中文變問(wèn)號(hào),如:??? 2.2 中文變奇怪字符,如:?? ?¥? 或者 ??o? 2.3 中文變“復(fù)雜中文”,如:浣犲ソ 2.4 中文變成一堆黑色菱形+問(wèn)號(hào),如:????? 3. Web開發(fā)中涉及到的中文編解碼 3.1 URL中出現(xiàn)的中文 3.2 Form表單中出現(xiàn)的中文 3.3 JSP中涉及的編碼 3.4 文件的上傳和下載中涉及到的中文亂碼 4. 總結(jié) 1. 字符編碼理論簡(jiǎn)述

          本文主要是圍繞Web開發(fā)中涉及到的中文編碼這一常見問(wèn)題展開,包括了對(duì)字符編碼基礎(chǔ)理論的簡(jiǎn)述以及常見幾種編碼標(biāo)準(zhǔn)的介紹。其中包括:ASCII、ISO8859-1、Unicode、GBK。下面先對(duì)這些字符編碼集進(jìn)行簡(jiǎn)單的介紹。

          1.1 ASCII

          ASCII也就是美國(guó)信息交換標(biāo)準(zhǔn)碼,采用單字節(jié)編碼方案,但是編碼只用了后七位字節(jié),表示范圍0-127共128個(gè)字符。ASCII碼相對(duì)于其它編碼也是最早出現(xiàn)的。從上世紀(jì)60年代提出開始,到1986年最終定型。

          為什么選擇7位編碼?ASCII在最初設(shè)計(jì)的時(shí)候需要至少能表示64個(gè)碼元:包括26個(gè)字母+10個(gè)數(shù)字+圖形標(biāo)示+控制字符,如果用6bit編碼,可擴(kuò)展部分沒(méi)有了,所以至少需要7bit。那么8bit呢?最終也被標(biāo)準(zhǔn)委員會(huì)否定,原因很簡(jiǎn)單:滿足編碼需求的前提下,最小化傳輸開銷。

          1.2 ISO8859-1

          ISO-8859-1也被稱為L(zhǎng)atin1,使用單字節(jié)8bit編碼,可以表示256個(gè)西歐字符。其隸屬于ISO8859標(biāo)準(zhǔn)的一部分,還有ISO8859-2、ISO8859-3等等。每一種編碼都對(duì)應(yīng)一個(gè)地區(qū)的字符集。比如:ISO8859-1表示西歐字符,ISO-8859-16表示中歐字符集,等等。

          1.3 Unicode

          不管是ASCII還是ISO8859-1,其編碼范圍都是有局限的。而Unicode標(biāo)準(zhǔn)的目標(biāo)就是消除傳統(tǒng)編碼的局限性。

          這里的局限性一方面指編碼范圍的局限性:比如ASCII只能表示128個(gè)字符。還有編碼兼容性方面的局限性:比如ISO8859代表的一系列編碼字符集雖然可以表示大部分國(guó)家地區(qū)的字符,但是彼此的兼容性做的不好。Unicode的目標(biāo)就如同其名稱的含義一樣:“實(shí)現(xiàn)字符編碼統(tǒng)一”

          Unicode標(biāo)準(zhǔn)的實(shí)現(xiàn)方案有如下三種:UTF-8、UTF-16和UTF-32**.

          UTF-8是變長(zhǎng)編碼,使用1到4個(gè)字節(jié)。UTF-8在設(shè)計(jì)時(shí)考慮到向前兼容,所以其前128個(gè)字符和ASCII完全一樣,也就是說(shuō),所有ASCII同時(shí)也都符合UTF-8編碼格式。其格式如下:

          0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

          字節(jié)首部為0的話,也就是前面說(shuō)的ASCII了。此外,字節(jié)首部連續(xù)1的個(gè)數(shù)就代表了該字符編碼后所占的字節(jié)數(shù)。目前全世界的網(wǎng)頁(yè)編碼絕大多數(shù)使用的就是UTF-8,占比接近90%。

          UTF-16也是變長(zhǎng)編碼,但其最初是固定16-bit寬度的定長(zhǎng)編碼,主要因?yàn)閁nicode涵蓋的字符太多了。兩字節(jié)更本不夠用!

          UTF-32是32-bit定長(zhǎng)編碼,優(yōu)點(diǎn):定長(zhǎng)編碼在處理效率上相對(duì)于變長(zhǎng)編碼要高,此外,可通過(guò)索引訪問(wèn)任意字符是其另一大優(yōu)勢(shì);缺點(diǎn)也很明顯:32bit太浪費(fèi)了!存儲(chǔ)效率太低!

          big-endian和little-endian?在多字節(jié)編碼標(biāo)準(zhǔn)中可能會(huì)遇到這樣的問(wèn)題:假如一個(gè)字符用兩個(gè)字節(jié)表示,那么當(dāng)讀取這個(gè)字符的時(shí)候,哪個(gè)字節(jié)表示高有效位?哪個(gè)表示低有效位呢?這就涉及到字節(jié)的存儲(chǔ)順序問(wèn)題。在Unicode中UTF-16和UTF-32都會(huì)面臨這個(gè)問(wèn)題。通常用BOM(Byte Order Mark)來(lái)進(jìn)行區(qū)分。BOM用一個(gè)"U+FEFF"來(lái)表示,這個(gè)值在 Unicode中是沒(méi)有對(duì)應(yīng)字符的。不僅可以用其來(lái)指定字節(jié)順序,還可以表示字節(jié)流的編碼方式。

          System.out.println("len1:" + "a".getBytes("UTF16").length); System.out.println("len2:" + "aa".getBytes("UTF16").length);

          輸出結(jié)果:

          len1:4

          len2:6

          為什么是4和6,不應(yīng)該是2和4嗎!?。輸出編碼后的字節(jié)序列可以發(fā)現(xiàn),起始的兩個(gè)字節(jié)都是:"fe ff"。

          Java的char類型用什么編碼格式?Java語(yǔ)言規(guī)范規(guī)定了Java的char類型使用的是UTF-16。這就是為什么Java的char占用兩個(gè)字節(jié)的原因。此外,Java標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)的對(duì)char與String的序列化規(guī)定使用UTF-8。Java的Class文件中的字符串常量與符號(hào)名字也都規(guī)定用UTF-8編碼。這大概是當(dāng)時(shí)設(shè)計(jì)者為了平衡運(yùn)行時(shí)的時(shí)間效率(采用定長(zhǎng)編碼的UTF-16,當(dāng)然,在設(shè)計(jì)java的時(shí)候UTF-16還是定長(zhǎng)的)與外部存儲(chǔ)的空間效率(采用變長(zhǎng)的UTF-8編碼)而做的取舍。

          1.4 GBK

          GBK是用于對(duì)簡(jiǎn)體中文進(jìn)行編碼。每個(gè)字符用兩字節(jié)表示,同時(shí)兼容GB2312標(biāo)準(zhǔn)。

          2. 可能發(fā)生的中文亂碼

          這一小節(jié)介紹軟件開發(fā)中常見的中文編碼亂碼問(wèn)題,在下面示例中:對(duì)于給定的一個(gè)包含中文的字符串"你好Java",看一下都會(huì)出現(xiàn)哪些亂碼問(wèn)題。

          2.1 中文變問(wèn)號(hào),如:????? "你好Java" ------> "??Java"

          這種情況一般是由于中文字符經(jīng)ISO8859-1編碼造成的。下面是編碼的具體過(guò)程:

          原字符串:"你好Java"

          你 好 J a v a 4f60 597d 4a 61 76 61

          經(jīng)ISO8859-1編碼后:

          你 好 J a v a 3f 3f 4a 61 76 61

          編碼后字符串:"??Java"

          String str = "你好Java"; System.out.println(byteToHexString(str.getBytes(CHARSET_ISO88591))); System.out.println(new String(str.getBytes(CHARSET_ISO88591))); 輸出: 3f 3f 4a 61 76 61 ??Java

          我們知道ISO8859-1是單字節(jié)編碼,而對(duì)于漢字已經(jīng)超出ISO8859-1的編碼范圍,會(huì)被轉(zhuǎn)化為"3f",我們查表可知,"3f"對(duì)應(yīng)的字符正是"?"。

          中文變問(wèn)號(hào)的亂碼情況是非常常見的,大部分開源軟件的默認(rèn)編碼設(shè)置成了ISO8859-1,這點(diǎn)需要格外注意。

          2.2 中文變奇怪字符,如:?? ?¥? 或者 ??o? "你好Java" ------> "?? ?¥?Java"

          原字符串:"你好Java"

          你 好 J a v a 4f60 597d 4a 61 76 61

          經(jīng)UTF-8編碼后,一個(gè)中文用三個(gè)字節(jié)表示:

          你 | 好 | J| a| v| a ---|---|---|---|---|---|---|--- e4 bd a0 | e5 a5 bd | 4a| 61| 76| 61

          亂碼原因:UTF8編碼或GBK編碼,再由ISO8859-1解碼。對(duì)照ISO8859-1編碼表后發(fā)現(xiàn):e4 bd a0分別對(duì)應(yīng)三個(gè)字符:"?? ",e5 a5 bd分別對(duì)應(yīng)三個(gè)字符"?¥?",

          2.3 中文變“復(fù)雜中文”如:浣犲ソ

          下面依然是"你好Java"經(jīng)過(guò)UTF-8編碼后對(duì)應(yīng)的字節(jié)序列:

          你 | 好 | J| a| v| a ---|---|---|---|---|---|---|--- e4 bd a0 | e5 a5 bd | 4a| 61| 76| 61

          在GBK表中查找:e4 bd對(duì)應(yīng)字符:"浣",a0 e5對(duì)應(yīng)字符:"犲",a5 bd對(duì)應(yīng)字符:"ソ"

          同理,如果GBK編碼的中文用UTF-8來(lái)解碼的話,同樣會(huì)出現(xiàn)亂碼問(wèn)題。

          2.4 中文變成一堆黑色菱形+問(wèn)號(hào),如:?????

          首先問(wèn)號(hào)+黑色菱形的字符是Unicode中的"REPLACEMENT CHARACTER",該字符的主要作用是用來(lái)表示不識(shí)別的字符。 所以產(chǎn)生亂碼的原因可能有很多,下面通過(guò)原字符串:"你好Java",重現(xiàn)一種亂碼方式:

          原字符串:String str = "你好Java" 你 | 好 | J| a| v| a ---|---|---|---|---|--- 4f60 | 597d | 4a| 61| 76| 61 UTF-16編碼后 fe ff 4f 60 59 7d 0 4a 0 61 0 76 0 61

          其中"fe ff"就是字節(jié)流起始的BOM標(biāo)識(shí)符。"fe ff"在Unicode標(biāo)準(zhǔn)中屬于"noncharacters",只用于內(nèi)部使用。所以, 在輸出該字節(jié)序列的時(shí)候,沒(méi)有該碼元對(duì)應(yīng)的字符,對(duì)于不識(shí)別字符,就會(huì)用??替代。

          3. Web開發(fā)中涉及到的中文編解碼

          Web中的數(shù)據(jù)大多通過(guò)http協(xié)議進(jìn)行傳輸,所涉及到的一些編解碼問(wèn)題都圍繞著http協(xié)議。下面以Tomcat作為Web服務(wù)器, 探討下一個(gè)完整的請(qǐng)求響應(yīng)流程中哪些地方會(huì)涉及到中文的編解碼。

          3.1 url編解碼

          web環(huán)境中的中文亂碼問(wèn)題,實(shí)驗(yàn)如下:

          jsp中的form表單: 用戶名: 地址 后端使用SpringMVC的Controller: @Controller() @RequestMapping("/manager") public class ManagerController { @RequestMapping("/test/{param}") @ResponseBody public String test(@PathVariable String param, HttpServletRequest request){ String name = request.getParameter("name"); System.out.println("name:" + name + ",param:" + param); return "test"; } }

          表單中填入內(nèi)容: 用戶名:你好 Java 地址:123 提交請(qǐng)求,firebug中的顯示的url如下:

          http://localhost:8080/fdyuntu-ssm/manager/codec/%E4%BD%A0%E5%A5%BD

          查閱編碼可以,firefox對(duì)url中出現(xiàn)的中文使用了UTF-8的編碼方式。之所以u(píng)rl中出現(xiàn)%,這是因?yàn)楦鶕?jù)URL編碼規(guī)范,瀏覽器會(huì)將非ASCII字符編成16進(jìn)制后,每個(gè)字節(jié)前需要加%。

          后端控制臺(tái)輸出:

          name:?? ?¥? Java,param:?? ?¥?

          可見無(wú)論是url中的中文信息或是post表單中的中文都出現(xiàn)了亂碼現(xiàn)象,從前一節(jié)中關(guān)于亂碼情況的分析來(lái)看,這里應(yīng)該是中文字符經(jīng)過(guò)瀏覽器UTF-8編碼后,Server端用ISO8859-1進(jìn)行解碼所致。下面逐個(gè)分析url和post表單如何進(jìn)行編解碼的。

          在tomcat中url的byte -> char的轉(zhuǎn)換是在org.apache.catalina.connector.CoyoteAdapter類的convertURI(MessageBytes uri, Request request)方法中執(zhí)行的,源碼如下:

          protected void convertURI(MessageBytes uri, Request request)throws Exception { ByteChunk bc = uri.getByteChunk(); int length = bc.getLength(); CharChunk cc = uri.getCharChunk(); cc.allocate(length, -1); //這里獲取的connector的URIEncoding屬性,即server.xml文件中connector元素的URIEncoding屬性 String enc = connector.getURIEncoding(); if (enc != null) { B2CConverter conv = request.getURIConverter(); try { if (conv == null) { conv = new B2CConverter(enc, true); request.setURIConverter(conv); } else { conv.recycle(); } } catch (IOException e) { log.error("Invalid URI encoding; using HTTP default"); connector.setURIEncoding(null); } if (conv != null) { try { conv.convert(bc, cc, true); uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength()); return; } catch (IOException ioe) { request.getResponse().sendError( HttpServletResponse.SC_BAD_REQUEST); } } } // 如果沒(méi)有配置URIEncoding,則在ByteChunk中默認(rèn)使用ISO8859-1。 byte[] bbuf = bc.getBuffer(); char[] cbuf = cc.getBuffer(); int start = bc.getStart(); for (int i = 0; i < length; i++) { cbuf[i] = (char) (bbuf[i + start] & 0xff); } uri.setChars(cbuf, 0, length); }

          在org.apache.tomcat.util.buf.ByteChunk中可以看到默認(rèn)編碼的定義:

          public final class ByteChunk implements Cloneable, Serializable { //。。。 public static final Charset DEFAULT_CHARSET = B2CConverter.ISO_8859_1; //。。。 }

          所以對(duì)于請(qǐng)求url中的中文,我們按UTF-8進(jìn)行編碼,在服務(wù)端卻按ISO8859-1進(jìn)行解碼,所以出現(xiàn)亂碼現(xiàn)象。我們可以再Tomcat的server.xml中指定url的編解碼格式,如下:

          此時(shí)重復(fù)上面實(shí)驗(yàn),后端控制臺(tái)輸出:name:?? ?¥? Java,param:你好

          雖然url中的參數(shù)可以正常顯示了,但是form表單中的參數(shù)name依然亂碼,下面進(jìn)一步分析。

          3.2 form表單元素的編解碼

          name參數(shù)的編碼依然是亂碼的,為啥?首先定位form表單中參數(shù)是在哪里進(jìn)行解碼的。Form表單中的字符解碼時(shí)機(jī)是發(fā)生在第一次調(diào)用request.getParameter時(shí),可以通過(guò)request.setCharacterEncoding設(shè)置。需要注意的是setCharacterEncoding必須在getParameter之前調(diào)用!否則,setCharacterEncoding不會(huì)起作用。

          Tomcat中HttpServletRequest接口的實(shí)現(xiàn)類是org.apache.catalina.connector.Request。下面是Request類中g(shù)etParameter源碼:

          @Override public String getParameter(String name) { //判斷參數(shù)是否被解析過(guò) if (!parametersParsed) { parseParameters();//第一次參數(shù)解析 } return coyoteRequest.getParameters().getParameter(name); } //下面是parseParameters部分源碼 protected void parseParameters() { //設(shè)為true,表示參數(shù)已解析過(guò) parametersParsed = true; //Parameters對(duì)象封裝了form表單參數(shù) Parameters parameters = coyoteRequest.getParameters(); boolean success = false; try { // Set this every time in case limit has been changed via JMX parameters.setLimit(getConnector().getMaxParameterCount()); //獲取字符編碼格式 String enc = getCharacterEncoding(); boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI(); if (enc != null) { //getCharacterEncoding不為null,則對(duì)應(yīng)設(shè)置編碼方式 parameters.setEncoding(enc); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding(enc); } } else { //如果enc為null,則編碼方式設(shè)置為DEFAULT_CHARACTER_ENCODING,也就是ISO8859-1 parameters.setEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); } } parameters.handleQueryParameters(); 。。。 } }

          從以上源碼中可以看出為什么需要在第一次調(diào)用getParameter之前設(shè)置CharacterEncoding。因?yàn)榈谝淮螆?zhí)行parseParameters時(shí),會(huì)把parametersParsed變量設(shè)為true。所以parseParameters只會(huì)在第一次getParameter時(shí)調(diào)用。有時(shí)會(huì)出現(xiàn)這么一種怪像:通過(guò)request.getCharacterEncoding()得到的是我們認(rèn)為正確的編碼字符集,但是request.getParameter得到的依然是亂碼。此時(shí)就需要考慮下我們調(diào)用setCharacterEncoding之前是否已經(jīng)調(diào)用過(guò)getParameter方法了。

          經(jīng)過(guò)上面的分析后,對(duì)于form表單參數(shù)亂碼問(wèn)題就很好解決了,在第一次調(diào)用request.getParameter方法前,通過(guò)request.setCharacterEncoding("Expected_Encoding");設(shè)置即可。這一步可以用Servlet標(biāo)準(zhǔn)中的Filter實(shí)現(xiàn),不過(guò),常用的MVC框架中已經(jīng)有現(xiàn)成的Filter實(shí)現(xiàn)了,比如SpringMVC中的org.springframework.web.filter.CharacterEncodingFilter,如下:

          @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) { request.setCharacterEncoding(this.encoding);//設(shè)置指定的編碼 if (this.forceEncoding) { response.setCharacterEncoding(this.encoding); } } filterChain.doFilter(request, response); } 3.3 JSP中涉及的編碼

          jsp中可以通過(guò)page指令指定一些編碼參數(shù),如下:

          pageEncoding="UTF-8"在什么時(shí)候起作用?

          在Servlet標(biāo)準(zhǔn)中,jsp最終也會(huì)被編譯成一個(gè)servlet。index.jsp->index_jsp.java.pageEncoding="UTF-8"就是在這個(gè)解析過(guò)程中起作用的。

          contentType="text/html; charset=UTF-8"的作用?

          contentType是響應(yīng)頭中特定信息,主要的作用是告訴瀏覽器response中存放的主體對(duì)象類型和編碼,這樣瀏覽器就可以對(duì)指定類型進(jìn)行正確解碼,保證了數(shù)據(jù)在server和client端的一致性。當(dāng)進(jìn)行Servlet編程的時(shí)候,可以手動(dòng)進(jìn)行設(shè)置,如下:

          response.setContentType("text/html; charset=UTF-8"); 3.4 文件的上傳和下載中涉及到的中文亂碼

          Web中的文件作主要是上傳和下載,這個(gè)過(guò)程也是依托于Http協(xié)議作為數(shù)據(jù)載體。所以,最終是否亂碼重點(diǎn)在于是否正確的設(shè)置http的request、response的header中的相關(guān)字段。如ContentType、Content-Disposition的設(shè)定等。如下:

          response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("application/x-msdownload"); response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

          這里需要注意的是Content-Disposition的filename屬性值,如果fileName含有中文,那么要格外注意fileName字符串的編碼格式。在rfc5987對(duì)于HTTP的Header中參數(shù)的編碼做出了明確的規(guī)定:

          By default, message header field parameters in Hypertext Transfer Protocol (HTTP) messages cannot carry characters outside the ISO-8859-1 character set.

          也就是說(shuō)默認(rèn)情況下,Http的Header中的參數(shù)只能用ISO-8859-1字符集中的字符,那么是否意味著Content-Disposition中的fileName字符串也要轉(zhuǎn)成ISO-8859-1了呢?答案是:NO!原因如下:Content-Disposition其實(shí)不屬于Http/1.1標(biāo)準(zhǔn)。這在RFC2616中有明確的說(shuō)明。只因?yàn)槠涫褂脧V泛,HTTP才對(duì)其支持。在rfc6266中也詳細(xì)介紹了Content-Disposition的filename參數(shù)含義和用法。下面是對(duì)于下載包含中文名稱的文件時(shí)的解決方案。

          解決方案

          最簡(jiǎn)單就是直接用ISO8859-1對(duì)文件名進(jìn)行編碼,大多數(shù)瀏覽器都支持。如下:

          exportFileName.getBytes("UTF-8"),"ISO8859-1");//這里的UTF-8也可能是別的編碼,主要依據(jù)系統(tǒng)默認(rèn)的編碼來(lái)設(shè)定。

          或通過(guò)其它編碼,如UTF-8。

          response.addHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(exportFileName, "UTF8")); 4. 總結(jié)

          編解碼問(wèn)題是多語(yǔ)言交互系統(tǒng)中必然要面對(duì)的問(wèn)題,尤其對(duì)于中文環(huán)境中的開發(fā)者來(lái)說(shuō),在入門階段或多或少都會(huì)遇到此類問(wèn)題。亂碼問(wèn)題本質(zhì)就是通信雙方使用的標(biāo)準(zhǔn)不一致。所以,解決亂碼問(wèn)題的方法其實(shí)也很簡(jiǎn)單,統(tǒng)一下編解碼標(biāo)準(zhǔn)即可。此外,深入理解各種編碼標(biāo)準(zhǔn)的原理和關(guān)系也非常重要,在以后遇到類似問(wèn)題的時(shí)候能夠更加準(zhǔn)確的判斷出造成亂碼的原因。



          【本文地址】

          公司簡(jiǎn)介

          聯(lián)系我們

          今日新聞

          推薦新聞

          專題文章
            CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有
            黄色免费网站在线看,韩国精品在线观看,韩国美女一区二区,99国产热 平原县| 宁阳县| 来凤县| 化隆| 布尔津县| 泸水县| 建瓯市| 夏邑县| 乌恰县| 汉源县| 依兰县| 封开县| 毕节市| 巴林左旗| 郓城县| 定结县| 托克托县| 富锦市| 栾川县| 贵港市| 武穴市| 揭西县| 西充县| 明溪县| 启东市| 新干县| 张家口市| 无为县| 贵德县| 柯坪县| 兴文县| 常州市| 敦煌市| 廉江市| 额济纳旗| 宁海县| 于田县| 肇东市| 辰溪县| 柞水县| 鄂温| http://444 http://444 http://444 http://444 http://444 http://444