Почему этот веб-сервер возвращает код 404 для Indy, но код 200 для каждого браузера?
У меня есть один URL, который прекрасно работает во всех браузерах (5 протестировано на 2 компьютерах), но если я пытаюсь получить содержимое страницы с помощью Get() клиента Indy Http, он возвращает код ошибки 404, страница не найдена. Это с последней сборкой Indy SVN (4985).
Почему этот веб-сервер возвращает код 404 для Indy, но код 200 для каждого браузера?
Я подозреваю, что это может быть ошибка в Indy из-за символа "#" в URL (Indy обрезает все после #). Если так, есть ли способ обойти это. Может заменить символ # на escape-код?
Вот мой пример кода. Все, что для этого нужно, - это Delphi с компонентами Indy, а также форма с кнопкой и памяткой.
procedure TForm1.Button1Click(Sender: TObject);
var HTTPCLIENT1: TIdHTTP;
begin
try
try
HTTPCLIENT1 := TIdHTTP.Create(nil);
Memo1.Clear;
with HTTPCLIENT1 do
begin
HandleRedirects := True;
Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31';
Memo1.Text := Get('http://www.visionofhumanity.org/gpi-data/#/2011/scor/');
Caption := ResponseText;
end;
except
On e: Exception do
begin
Memo1.Lines.Add('Exception: '+e.Message);
end;
end;
finally
HTTPCLIENT1.Free;
end;
end;
2 ответа
#
является зарезервированным символом в URL. Если вы хотите использовать зарезервированные символы внутри URL-адреса, вам необходимо их кодировать по URL. TIdHTTP
не делает это для вас. Он требует, чтобы вы передали закодированный URL, но вместо этого вы передаете незашифрованный URL. поскольку #
не закодирован, обрабатывается как якорь и удаляется, поэтому вы на самом деле запрашиваете http://www.visionofhumanity.org/gpi-data/
Хенсе 404 ответ.
#
URL-кодируется как %23
так что используйте это:
Memo1.Text := Get('http://www.visionofhumanity.org/gpi-data/%23/2011/scor/');
Или это:
Memo1.Text := Get(TIdURI.URLEncode('http://www.visionofhumanity.org/gpi-data/#/2011/scor/'));
Обновление: я разыскал проблему. Это другое TIdURI
ошибка разбора, на этот раз связанная с наличием /
персонаж после #
персонаж. TIdURI
проверяет /
символов, прежде чем он проверяет на #
символ, поэтому якорная часть URL заканчивалась в TIdURI.Path
собственность (ранее это заканчивалось в TIdURI.Params
собственности) и, таким образом, представлены на сервер. Я проверил новое исправление (SVN rev 4987).
Ваше подозрение верно. Вы включили #
раздел адреса в вашем запросе. Браузеры не делают этого, потому что этот раздел зарезервирован для навигации внутри страницы. Сервер не знает об этом, поэтому он пытается извлечь ресурс, который соответствует полному URL, который вы ему дали, включая #
и все после. Ничто не соответствует, так что это терпит неудачу со статусом 404.
Либо сделайте так, как это делают браузеры, и удалите этот раздел из URL-адреса перед отправкой запроса на сервер, либо обновите Indy до версии 4987, чтобы это произошло автоматически. Простое спасение персонажа продолжит давать статус 404.