HTTP-ответ с перенаправлением, но без возврата?

Я хочу, чтобы браузер отражал другой URL-адрес, отличный от того, который использовался для создания запроса, но без обращения к серверу.

Я бы, возможно, сделал это:

POST /form HTTP/1.1
...

... и затем вернуться:

HTTP/1.1 200 OK
Location: /hello

Но это вызовет перенаправление, браузер снова запросит URL /hello.

Я хотел бы просто сообщить браузеру, что, хотя запрос, который вы только что отправили, был POST /some_url, фактический ресурс, который я сейчас возвращаю, на самом деле называется GET /hello/1, но без предварительной обработки туда и обратно. то есть местонахождение: ...

Есть ли способ сделать это с помощью JavaScript или атрибута base=""? Это скажет браузеру запросить /hello/1, когда я нажму F5 (обновить) вместо этого, опубликовать предупреждение об отправке?


person John Leidegren    schedule 01.04.2009    source источник


Ответы (2)


HTTP/1.1 200 OK
Location: /hello

На самом деле это, вероятно, не сработает; это должен быть статус 30x, а не 200 («303 See Other» лучше всего подходит для ответа на POST), а «Location» должен быть полным абсолютным URL-адресом.

(Если ваш сценарий просто говорит «Местоположение: /relativeurl» без статуса 30x, серверы CGI обычно выполняют внутреннюю переадресацию, извлекая новый URL-адрес и возвращая его, не сообщая браузеру, что произошло что-то смешное. Это может звучать так, как вы хотите, но это на самом деле это не так, потому что с точки зрения браузера он ничем не отличается от исходного скрипта, возвращающего 200 и прямую страницу.)

Но это вызовет перенаправление, браузер снова запросит URL /hello.

На практике это, вероятно, не так плохо, как вы думаете, благодаря поддержке активности HTTP/1.1. Клиент должен иметь возможность немедленно ответить на перенаправление (в следующем пакете), если он находится на том же сервере.

Есть ли способ [...] Это скажет браузеру запросить /hello/1, когда я нажму F5 (обновить) вместо этого, опубликовать предупреждение об отправке?

Неа. Придерживайтесь модели POST-Redirect-GET для решения этой проблемы.

person bobince    schedule 01.04.2009
comment
Хорошо, вот в чем дело, есть причина, по которой я не хочу туда и обратно, и это не предварительная подготовка. Предпочтительно, если я могу подготовить ответ в сочетании с запросом, я мог бы захотеть передать и/или манипулировать этим запросом в зависимости от POST, и это не может быть сделано так же легко, если я туда и обратно. - person John Leidegren; 03.04.2009
comment
Я попытался использовать уникальный идентификатор и передать его туда и обратно, поместив его в файл cookie с путем, установленным на /hello/1. Затем это значение будет получено с помощью GET /hello/1 и на стороне сервера, я смогу получить любое состояние, которое я кэшировал для этого запроса. Это работает, но что вы думаете? - person John Leidegren; 03.04.2009
comment
Что я обычно делаю, так это добавляю параметр в строку запроса перенаправления для последующего запроса. Поскольку файлы cookie используются всеми страницами/окнами, открытыми на сайте, этот параметр гарантирует, что информация об ответе после действия поступает в нужное окно. - person bobince; 03.04.2009
comment
(Затем я подкрепляю это значением метки времени, чтобы информация о пост-действии «срок действия» истекала через некоторое время. Так что, если вы сделаете закладку или иным образом вернетесь к тому же URL-адресу, та же информация больше не появится.) - person bobince; 03.04.2009
comment
Однако если у вас есть много данных для вывода в ответ на действие, это может быть не так практично; вы могли бы временно сохранить его в базе данных и указать его в параметре, но это начинает немного раздражать при реализации. - person bobince; 03.04.2009

Нет. Http не имеет состояния, и на каждый запрос есть один ответ. Когда вы публикуете, вам нужно немедленно перенаправить на страницу получения, чтобы предотвратить двойное сообщение — вы не хотите, чтобы оно сидело на этом URL-адресе сообщения. Перенаправление — это то, что сообщает браузеру, что он находится на новой странице. Именно так это работает.

person DGM    schedule 01.04.2009