У меня есть эта функция в Delphi 2009/2010.
Он возвращает мусор, теперь, если я изменю типы char, pchar на Ansichar, Pansichar, он вернет текст, но весь иностранный текст Unicode - мусор. это сводит меня с ума. Я пробовал всякие штуки уже 2 дня. Я думал, что понял эту ерунду с юникодом, но, думаю, я не помог. Пожалуйста, спасибо, Филипп Ватель
function GetInetFileAsString(const fileURL: string): string;
const
C_BufferSize = 1024;
var
sAppName: string;
hSession,
hURL: HInternet;
Buffer: array[0..C_BufferSize] of Char;
BufferLen: DWORD;
strPageContent: string;
strTemp: string;
begin
Result := '';
sAppName := ExtractFileName(Application.ExeName);
hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil,
nil, 0);
try
hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0);
try
strPageContent := '';
repeat
InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
SetString(strTemp, PChar(@buffer), BufferLen div SizeOf(Char));
strPageContent := strPageContent + strTemp;
until BufferLen = 0;
Result := strPageContent;
finally
InternetCloseHandle(hURL)
end
finally
InternetCloseHandle(hSession)
end
end;
2 ответа
Начиная с 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;
Моя первая мысль — добавить в запрос правильный заголовок AcceptEncoding/CharSet:
Например:
Accept-Charset: ISO-8859-1, utf-8; q = 0,7, *; q = 0,7
Похожие вопросы
Новые вопросы
delphi
Delphi - это язык для быстрой разработки собственных приложений для Windows, macOS, Linux, iOS и Android с использованием Object Pascal. Название относится к языку Delphi, а также к его библиотекам, компилятору и IDE, которые используются для помощи в редактировании и отладке проектов Delphi.