用XMLHTTP Post/Get HTML页面时的中文乱码问题之完全Script解决方案

用XMLHTTP Post/Get HTML页面时的中文乱码问题之完全Script解决方案

关键词:VBScript, ASP, JavaScript, Java, XML

以前我曾经贴过一篇用XMLHTTP Post Form 的帖子,那里的代码中我Post E文的Value毫无问题,但是后来发现Post含有中文的表单时会出现乱码,原因当然是UTF-8 和GB2312 之间的转换问题了!TNND,打倒GB2312!大家都用UTF8多好。

用XMLHTTP Post Form时的表单乱码有两方面的原因——Post表单数据时中文乱码;服务器Response被XMLHTTP不正确编码引起的乱码。换句话说,本文主要解决两个问题——怎样正确Post中文内容&怎样正确显示得到的中文内容。

Part I Post中文内容

先看看E文的表单是怎么提交的:

<SCRIPT language="JavaScript">
strA = "submit1=Submit&text1=scsdfsd";
var oReq = new ActiveXObject("MSXML2.XMLHTTP");
oReq.open("POST","http://ServerName/VDir/TstResult.asp",false);
oReq.setRequestHeader("Content-Length",strA.length);  
oReq.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded");
oReq.send(strA);
</ScRIPT>

如果把strA = "submit1=Submit&text1=scsdfsd";换成:
strA = "submit1=Submit&text1=中文";

你会发现提交上去的东东根本不对,ASP中Request.Form("Text1")根本取不到值。俺用Request.BinaryRead把一个HTML Form中的Post内容写出来看了看,才发现问题——Form提交时也要编码的,编码后的中文是类似于%??%??的转义字符,比如“中文”就被编码为:%D6%D0%CE%C4。呵呵,也怪俺笨,人家CONTENT-TYPE里明明写的清清楚楚——application/x-www-form-urlencoded,urlencoded嘛当然就是这个样子了。既然这样,那我们也知道该怎么办了——自己做转换,代码见下:

<SCRIPT language="VBScript">
Function URLEncoding(vstrIn)
    strReturn = ""
    For i = 1 To Len(vstrIn)
        ThisChr = Mid(vStrIn,i,1)
        If Abs(Asc(ThisChr)) < &HFF Then
            strReturn = strReturn & ThisChr
        Else
            innerCode = Asc(ThisChr)
            If innerCode < 0 Then
                innerCode = innerCode + &H10000
            End If
            Hight8 = (innerCode  And &HFF00)/ &HFF
            Low8 = innerCode And &HFF
            strReturn = strReturn & "%" & Hex(Hight8) &  "%" & Hex(Low8)
        End If
    Next
    URLEncoding = strReturn
End Function


strA = URLEncoding("submit1=Submit&text1=中文")
oReq = CreateObject("MSXML2.XMLHTTP")
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false
oReq.setRequestHeader "Content-Length",Len(strA)
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded"
oReq.send strA
</ScRIPT>

(在这里俺把前面的JavaScript的代码改成了VBScript,不是吃饱了撑的没事干,原因见后)

Part II.正确显示得到的中文内容

OK,如果你在Server端把Form的内容写到数据库/文件的话,你在那里看到的中文毫无问题,但是,假如你想看看Server的Response——问题来了:如果Response的结果不是XML,XMLHTTP.responseXML里当然是不会有东东的,那就用responseText好了,在代码的最后加一句:

alert(oReq.responseText)
看看俺们辛勤劳动的结果  :P

但是但是.....怎么所有的中文全变成了方格? (我打不出来,有兴趣自己去试,也不用Post,Get一个含有中文的网页就可以发现了。)

原因很简单:XMLHTTP得到Response时假定Response是UTF8编码的,如果Response是XML,那还可以通过encoding来指定编码,但HTML就不行了。(见鬼的GB2312,再次打倒!)所以它把含GB2312编码的HTML当成UTF8格式,不出错才有鬼!

不过好在还有补救的办法:XMLHTTP的responseBody 属性里包含的可是未解码的Resonse——"a raw undecoded bytes as received directly from the server" :),唯一的问题是,responseBody返回的是一个unsigned bytes数组,我们怎么去访问它,怎么把它转换成BSTR?

这就是为什么我在上面把代码改成VBScript的原因——VBScript Can do it,but JavaScript Cannot!

代码见下:
<SCRIPT language="VBScript">
Function URLEncoding(vstrIn)
    strReturn = ""
    For i = 1 To Len(vstrIn)
        ThisChr = Mid(vStrIn,i,1)
        If Abs(Asc(ThisChr)) < &HFF Then
            strReturn = strReturn & ThisChr
        Else
            innerCode = Asc(ThisChr)
            If innerCode < 0 Then
                innerCode = innerCode + &H10000
            End If
            Hight8 = (innerCode  And &HFF00)/ &HFF
            Low8 = innerCode And &HFF
            strReturn = strReturn & "%" & Hex(Hight8) &  "%" & Hex(Low8)
        End If
    Next
    URLEncoding = strReturn
End Function

Function bytes2BSTR(vIn)
    strReturn = ""
    For i = 1 To LenB(vIn)
        ThisCharCode = AscB(MidB(vIn,i,1))
        If ThisCharCode < &H80 Then
            strReturn = strReturn & Chr(ThisCharCode)
        Else
            NextCharCode = AscB(MidB(vIn,i+1,1))
            strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))
            i = i + 1
        End If
    Next
    bytes2BSTR = strReturn
End Function


strA = URLEncoding("submit1=Submit&text1=中文")
oReq = CreateObject("MSXML2.XMLHTTP")
oReq.open "POST","http://ServerName/VDir/TstResult.asp",false
oReq.setRequestHeader "Content-Length",Len(strA)
oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded"
oReq.send strA
alert bytes2BSTR(oReq.responseBody)
</ScRIPT>

嘿嘿,是不是很简单啊,用这个再试试看?一切OK!

(顺便说说byte(),这个东东在VBScript里的表现只能用妖来形容——对它调用VarType 返回8209——vbArray + vbByte,用LBound、UBound能拿到数组的上界下界,但是就是不能用name(i)的形式访问,搞得我以为在Script里根本没法处理这种类型,在bytes2BSTR函数里可以看到我是把它当成String来处理的——LenB/MidB什么的,发现这点纯属意外——我开始往这个函数里传的是XMLHTTP.responseText,想一个Byte一个Byte地看看里面到底有点什么,后来一时性起把responseText改成responseBody,结果就中奖了,哈哈)

最后的废话:
1、以上代码在MSXML Parser 3 Release+VBScript 5.5环境下通过。那位兄弟有早一点版本的Script可以帮我试试看能不能成。
2、一直以为JavaScript vs VBScript应该是JavaScript略好,所以有时候想彻底抛弃VBScript,ASP Server/Client统统用JavaScript,看来未必是个好主意。

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 需要使用AJAX技术来实现返回数据,具体实现步骤如下: 1. 编写一个后台接口,接收前端传递的数据并处理,然后返回数据。例如,使用Java编写一个Servlet。 2. 在前端页面中使用AJAX技术发送请求,获取后台返回的数据。 3. 在AJAX请求中需要设置dataType为json,这样返回的数据就是JSON格式的,而不是文本格式的。 4. 在后台接口中设置响应头的Content-Type为application/json;charset=utf-8,这样返回的数据就不会码。 5. 在前端页面中处理返回的数据,例如使用JavaScript解析JSON格式的数据,并将数据展示在页面中。 示例代码: 后台接口: ```java @WebServlet("/test") public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); out.print("{\"name\":\"张三\",\"age\":18}"); out.flush(); out.close(); } } ``` 前端页面: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>返回数据示例</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(function() { $("#btn").click(function() { $.ajax({ url: "/test", type: "get", dataType: "json", success: function(data) { $("#name").text(data.name); $("#age").text(data.age); } }); }); }); </script> </head> <body> <button id="btn">获取数据</button> <div>姓名:<span id="name"></span></div> <div>年龄:<span id="age"></span></div> </body> </html> ``` ### 回答2: 要实现返回数据不跳转页面,可以使用Ajax技术。Ajax是一种在不刷新整个页面的情况下,通过后台与服务器进行数据交互的技术。 首先,在前端页面中使用JavaScript编写Ajax请求,发送一个HTTP请求给服务器,实现数据的异步传输。可以使用原生的XMLHttpRequest对象或者使用jQuery框架提供的$.ajax()方法。 在后台服务器中,接收到Ajax请求后,处理请求并返回数据。在返回数据之前,需要确保返回的数据不会码。为了避免数据码,可以通过设置响应头的编码格式为UTF-8,确保数据以UTF-8编码进行传输。在Java后台可以使用以下代码来设置编码格式: ``` response.setCharacterEncoding("UTF-8"); // 设置响应头的编码格式为UTF-8 ``` 对于返回的数据,可以将其以JSON格式进行返回。JSON是一种轻量级的数据交换格式,广泛用于各种编程语言之间的数据交互。在后台可以使用相应的JSON库将数据转换成JSON格式,然后将其返回给前端。 在前端中,可以通过回调函数来处理后台返回的数据。一般情况下,可以在Ajax请求中设置成功回调函数,该函数会在后台成功返回数据被调用。在该函数中可以对返回的数据进行处理,可以将其显示在页面上或者进行其他操作。 通过以上步骤,就可以实现返回数据不跳转页面,并且保证返回的数据不会码。这样可以提升用户体验,同减少了页面的刷新次数,提高了网站的性能。 ### 回答3: 要实现返回数据不跳转页面且数据不码,可以使用Ajax技术来进行异步请求。具体步骤如下: 1. 在前端页面中,使用JavaScript创建一个Ajax对象。 2. 设置Ajax请求的相关参数,包括请求的URL地址、请求方式(GETPOST)、请求数据格式等。 3. 设置Ajax的回调函数,用于处理服务器返回的数据。 4. 发送Ajax请求,并将请求的数据作为参数传递给服务器端。 5. 在服务器端,根据接收到的请求数据进行相应的处理,并返回处理结果。 6. 在前端的回调函数中,通过获取服务器返回的数据,进行相应的操作。 在处理数据编码的问题上,可以采用UTF-8编码格式,确保数据不会出现码。 以下是一个简单的示例代码: 前端页面代码: ```javascript <script> function getData() { var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // 处理服务器返回的数据 var data = JSON.parse(this.responseText); // 对数据进行操作 console.log(data); } }; xmlhttp.open("GET", "data.php", true); xmlhttp.send(); } </script> ``` 服务器端代码(PHP示例): ```php <?php // 处理请求数据 $name = $_GET['name']; $age = $_GET['age']; // 进行相关操作 // ... // 返回数据 $data = array( 'name' => '张三', 'age' => 18 ); // 设置响应头部,确保数据不码 header('Content-Type:application/json;charset=utf-8'); // 将数据转换成JSON格式并输出 echo json_encode($data); ?> ``` 在上述示例中,前端页面调用getData()函数发送Ajax请求,服务器端接收请求并返回数据。前端通过回调函数处理服务器返回的数据,可以在控制台中查看输出结果。 需要注意的是,以上为简化的示例代码,实际情况中还需要考虑对请求和返回数据的安全性处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

x86

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值