Начиная с Delphi 2009, String
- это псевдоним для UnicodeString
, который содержит данные UTF-16. HTML-страница, с другой стороны, обычно кодируется с использованием многобайтовой кодировки Ansi (обычно в настоящее время UTF-8, но не всегда). Ваш текущий код будет работать только в том случае, если HTML кодируется как UTF-16, что очень редко. Вы не должны читать необработанные байты HTML в UnicodeString
напрямую. Сначала необходимо загрузить все данные в TBytes
, RawByteString
, TMemoryStream
или другой подходящий байт-контейнер по вашему выбору, а затем затем выполнить преобразование Ansi-> Unicode на основе набора символов, указанного в заголовок ответа HTTP «Content-Type». Вы можете использовать заголовок запроса Accept-charset
, чтобы сообщить серверу, на какую кодировку вы предпочитаете отправлять данные, и если сервер не может использовать эту кодировку, он должен отправить ответ 406 Not Acceptable
(хотя он МОЖЕТ отправить успешный ответ в недопустимом наборе символов, если он решит игнорировать заголовок вашего запроса, поэтому вы должны учитывать это).
Попробуйте что-то вроде этого:
function GetInetFileAsString(const fileURL: string): string;
const
C_BufferSize = 1024;
var
sAppName: string;
hSession, hURL: HInternet;
Buffer: array of Byte;
BufferLen: DWORD;
strHeader: String;
strPageContent: TStringStream;
begin
Result := '';
SetLength(Buffer, C_BufferSize);
sAppName := ExtractFileName(Application.ExeName);
hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
try
strHeader := 'Accept-Charset: utf-8'#13#10;
hURL := InternetOpenURL(hSession, PChar(fileURL), PChar(strHeader), Length(strHeader), 0, 0);
try
strPageContent := TStringStream.Create('', TEncoding.UTF8);
try
repeat
if not InternetReadFile(hURL, PByte(Buffer), Length(Buffer), BufferLen) then
Exit;
if BufferLen = 0 then
Break;
strPageContent.WriteBuffer(PByte(Buffer)^, BufferLen);
until False;
Result := strPageContent.DataString;
// or, use HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) to get
// the Content-Type header, parse out its "charset" attribute,
// and convert strPageContent.Memory to UTF-16 accordingly...
finally
strPageContent.Free;
end;
finally
InternetCloseHandle(hURL);
end
finally
InternetCloseHandle(hSession);
end;
end;