发送阿拉伯文本到Web服务

好吧,我很困惑。 我的问题是,我想我的Excel电子表格的内容发送到一个HTTP POST Web服务,UTF8编码 – 即我想支持阿拉伯文本。

我可以遍历电子表格的单元格写入stream:

Dim fsT 'As New Stream Set fsT = CreateObject("ADODB.Stream") fsT.Type = 2'Specify stream type - we want To save text/string data. fsT.Charset = "utf-8" 'Specify charset For the source text data. fsT.Open 'Open the stream And write binary data To the object 

我可以,如果我希望保存到一个文件,我的阿拉伯文本保存。

当我把这个发送给我的服务时,我把它作为一个二进制文件发送,这可能是我的失败。

 'Change stream type To binary fsT.Position = 0 fsT.Type = adTypeBinary 

其次是

  Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0") Call oHttp.Open("POST", pHtml, False) oHttp.setRequestHeader "Content-Type", "application/text" oHttp.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" Call oHttp.send(fsT.Read) 

不过,我也试图发送文本,而不改变streamtypes

 Call oHttp.send(fsT.ReadText) 

在这两种情况下,我的服务器上收到的阿拉伯语文本只是一系列的问号? ??? ??? 等等顺便说一下,如果我看看sft.ReadText的输出结果,我就可以在VBA上得到它。

所以 – 我可以输出到一个文件好,但没有任何其他的东西没有丢失我的文字。

我的VBA不是很好,我敢肯定我会被告知我有多愚蠢,但冒着这个风险,任何人都可以帮忙 – 我一直在尝试许多事物的排列,而我却无法得到文本发送过来。

从你的答案我得到一个怀疑。

你在做什么是以下几点:

您在二进制ADODB.Stream编写纯未编码的Unicode字节。 然后连接"" & fsT.Read你正在创build一个Unicodestring。 正如在https://msdn.microsoft.com/en-us/library/ms763706%28v=vs.85%29.aspx中提到的那样:“如果inputtypes是BSTR,那么响应总是被编码为UTF-8。 “ 所以IXMLHTTPRequest将把这个string编码为UTF-8。

带有.Charset = "utf-8"的文本ADODB.Stream在它的.ReadText也会有一个Unicodestring。 但是在更改为二进制文件之后,它将在其开始处具有UTF-8 BOM(EFBBBF)。 这个BOM是什么混淆你的web服务。

请尝试如果

  Set fsT = CreateObject("ADODB.Stream") fsT.Charset = "UTF-8" fsT.Type = 2 fsT.Open For Each cell In ActiveSheet.UsedRange.Cells fsT.WriteText cell.Value Next fsT.Position = 0 Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0") oHttp.Open "POST", pHtml, False oHttp.send "" & fsT.ReadText 

也将工作。 如果是这样,那么在我看来这是更清洁的解决scheme。

如果两个站点(服务器和客户端)在使用同一种语言(本例中为HTTP)并且服务器确实期望在POST请求正文中使用UTF-8编码的字节,那么它应该可以工作。

当然这是一个断言。 但我会certificate这一点。

所以我有以下简单的Java服务器运行:

 import java.net.*; import java.io.*; class SimplestServerPOST extends Thread { private ServerSocket srvSock = null; private Socket sock = null; private BufferedInputStream bin = null; private DataOutputStream out = null; private int contentLength = 0; private int c = 0; SimplestServerPOST(int port, int timeout) { super(); try { System.out.println("Server start."); srvSock = new ServerSocket(port, 5); srvSock.setSoTimeout(timeout); start(); } catch (Exception e) { e.printStackTrace(); } } public void run() { System.out.println("Server run."); while (true) { try { sock = srvSock.accept(); //Begin request-handling try { StringBuffer headerLine = new StringBuffer(""); bin = new BufferedInputStream(sock.getInputStream()); out = new DataOutputStream(sock.getOutputStream()); while ((c = bin.read()) >= 0) { if ((c == 10) || (c == 13)) { //if there is a linebreak, then the line ends if (c == 13) { //handle CRLF linebreak bin.mark(1); if (bin.read() != 10) bin.reset(); } if (headerLine.length() == 0) break; //the whole header section ends if the first empty line occurs //get the content-length header if (headerLine.toString().toLowerCase().startsWith("content-length")) { contentLength = Integer.parseInt(headerLine.toString().split(" ")[1]); } System.out.println(headerLine.toString()); headerLine.delete(0, headerLine.length()); //new headerline } else { headerLine.append((char)c); //get one byte for headerline } } byte[] buffer = new byte[contentLength]; bin.read(buffer); System.out.println(new String(buffer, "UTF-8")); FileWriter fw = new FileWriter("POSTContent.txt"); fw.write(new String(buffer, "UTF-8")); fw.close(); out.writeBytes("HTTP/1.1 200 OK\r\n"); out.writeBytes("Connection: close\r\n"); out.writeBytes("\r\n"); out.close(); } catch(Exception e) { e.printStackTrace(); } //End request-handling sock.close(); } catch (InterruptedIOException e) { try { int sSTo = srvSock.getSoTimeout(); // This is only to understand the functionality. //System.out.println("No requests for " + sSTo + "ms."); } catch (Exception et) { et.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } } protected void finalize() { if (srvSock != null) { try { srvSock.close(); } catch (Exception e) { e.printStackTrace(); } srvSock = null; } } } class SimplestServerPOSTMain { public static void main(String[] args) { SimplestServerPOST srv = new SimplestServerPOST(2000, 1000); } } 

我从下面的VBA发送一个POST请求到这个服务器:

 Sub test() Set oADOStream = CreateObject("ADODB.Stream") oADOStream.Type = 2 oADOStream.Charset = "utf-8" oADOStream.Open oADOStream.WriteText "Test umlauts: äöü", 1 oADOStream.WriteText "Test euro sign: €", 1 oADOStream.WriteText "Test arabic: " & ChrW(1587) & " " & ChrW(1588) & " " & ChrW(1589) & " " & ChrW(1590), 1 oADOStream.Position = 0 Set oWinHTTP = CreateObject("MSXML2.XMLHTTP.6.0") oWinHTTP.Open "POST", "http://192.168.0.10:2000", False 'oWinHTTP.Send oADOStream.ReadText oADOStream.Type = 1 oWinHTTP.Send oADOStream.Read End Sub 

结果是:

在这里输入图像描述

这个控制台是一个Linux控制台。 Windows控制台可能无法正确显示字符。 但是POSTContent.txt文件应该包含它们。

好的 – 谢谢你的帮助。 我不知道为什么,但没有任何build议的工作。 然而,我却find了一个适合我的解决scheme。 它是:

  1. 创build一个二进制stream,
  2. 将单元格值从Excel写入ByteArray – 并将字节数组写入stream中
  3. 发送stream – 重要的是连接一个空白string。

我所做的一个例子如下:

 Dim fsT 'As New Stream Set fsT = CreateObject("ADODB.Stream") fsT.Type = adTypeBinary 'Specify stream type - we want To save text/string data. Dim b() As Byte For Each cell In ActiveSheet.UsedRange.Cells b = cell.Value fsT.Write b Next fsT.Position = 0 Call oHttp.Open("POST", pHtml, False) oHttp.setRequestHeader "Content-Type", "application/text;charset=UTF-8" Call oHttp.send("" & fsT.Read) 

注意最后一行,如果我删除string的连接,它不会以阿拉伯语的forms来到服务器。

我想可能是这个问题的其他答案没有奏效的原因是,我得到的文本(cell.Value),而不是直接写入UniCode的stream。