WinInet HttpQueryInfo 可以返回原始字节吗? (带有 unicode 字符的 HTTP 标头)
Posted
技术标签:
【中文标题】WinInet HttpQueryInfo 可以返回原始字节吗? (带有 unicode 字符的 HTTP 标头)【英文标题】:Can WinInet HttpQueryInfo return raw bytes? (HTTP Headers with unicode characters) 【发布时间】:2012-09-19 01:22:59 【问题描述】:内置例程 HttpQueryInfo 返回一个字符串,而不是实际字节。通常这不是问题。
但是,最近我开始遇到服务器发出重定向的问题,其中位置标头字段包含包含非百分比编码的 unicode/或?人物。有什么办法吗?
var
vContent_Wide: WideString;
begin
vBufferSize := 4096;
GetMem(vBufferPtr, vBufferSize);
while True do
begin
TmpFakeCardinal := 0;
vErrorNone := HttpQueryInfo(
hHttpOpen_Request,
HTTP_QUERY_RAW_HEADERS_CRLF,
vBufferPtr,
vBufferSize,
TmpFakeCardinal
);
if (vErrorNone = False) then
begin
vErrorID := GetLastError;
if (vErrorID = ERROR_INSUFFICIENT_BUFFER) then
begin
FreeMem(vBufferPtr);
GetMem(vBufferPtr, vBufferSize);
end
else Break;
end
else
begin
vContent_Wide := PWideChar(vBufferPtr);
Result := vContent_Wide;
Break;
end
;
end;
FreeMem(vBufferPtr, vBufferSize);
【问题讨论】:
请编辑您的问题:添加您使用的某个 Delphi 版本的标签。不清楚是调用HttpQueryInfoA还是HttpQueryInfoW 什么是 vContent_Native?什么是 msxCopyPCharToStr ?你没有显示任何声明! 代码中的注释说明了。 Delphi 2007 将其映射到 HttpQueryInfoA,而 Delphi XE2(所有 unicode 版本)将其映射到 HttpQueryInfoW。 (而vContent_Native是对应的字符串类型) 但是我现在已经更正了代码以假设 Delphi XE2。 (但是API调用的“A”和“W”版本都存在这个问题。我来回做了很多实验) Indy 的TIdHTTP
组件使用IOHandler.DefStringEncoding
属性来决定使用哪个字符集来解码HTTP 标头。如果您想使用不同的解码字符集,您可以在发送请求之前设置DefStringEncoding
属性。
【参考方案1】:
URI 不支持未编码的 Unicode 字符。如果服务器在 Location
标头中发送非百分比编码的 Unicode 字符串,则服务器有问题,需要修复,因为这明显违反了 RFC 2616 section 14.30。我的猜测是服务器实际上发送的是未映射的 IRI (RFC 3987) 而不是 URI (RFC 3986)。 HTTP 不支持直接使用 IRI,它们必须映射到 URI(RFC 3987 定义了如何做到这一点)。
话虽如此,请检查将dwInfoLevel
参数设置为HTTP_QUERY_CUSTOM
是否允许HttpQueryInfo()
返回标头的原始字节。如果没有,那么您将无法将 WinInet 用于那些出现故障的服务器,因为 WinInet API 中没有其他函数可以访问 HTTP 标头。您必须找到另一个支持您需要的 HTTP 库,否则您可以下拉到 TCP/IP 层并在您自己的代码中手动实现 HTTP 协议。
【讨论】:
感谢您的回复雷米。我现在已经投票了,我希望今晚或明天晚些时候将其标记为已接受的答案:) 我没有成功使用 HTTP_QUERY_CUSTOM,但我现在正在测试你们关于 Indy 的 cmets。 解决方案最终是您在评论中其他地方建议的:将 Indy 的 TIdHTTP IOHandler.DefStringEncoding 设置为 UTF-8。这解决了两个不同客户的问题以上是关于WinInet HttpQueryInfo 可以返回原始字节吗? (带有 unicode 字符的 HTTP 标头)的主要内容,如果未能解决你的问题,请参考以下文章