Есть ли смысл для сервера предоставлять 200
ответ, когда GET
запрос сделан на несуществующий файл? Разве ответ не всегда должен быть 404
?
Вот заголовок ответа:
{'Date': 'Tue, 08 Jan 2019 22:56:26 GMT', 'Server': 'Apache', 'Strict-Transport-Security': 'max-age=31536000; preload', 'X-Frame-Options': 'SAMEORIGIN', 'XX-RequestId': 'pw01-225626->serv_31-225626', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'X-Content-Type-Options': 'nosniff', 'X-Permitted-Cross-Domain-Policies': 'none', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Content-Length': '20', 'Keep-Alive': 'timeout=5, max=100', 'Connection': 'Keep-Alive', 'Content-Type': 'application/json'}
Даже если Content-Length
говорит 20
мы получаем загружаемый zip-файл с нулевым байтом.
Да, есть случаи, когда имеет смысл вернуть ответ 200 для несуществующего файла. Ответ 200 указывает, что логический объект, который запрашивал клиент, существует. Совершенно разумно вернуть ответ, указывающий на то, что логическая сущность существует, даже если файл не существует, если существование файла и существование логической сущности не одно и то же.
Предположим, у меня есть файловая система, в которой каждый файл указывает имя пользователя с определенным статусом. Отсутствие файла не означает, что имя пользователя не существует, оно просто указывает, что имя пользователя не находится в этом конкретном статусе. В этом случае было бы ошибкой возвращать 403 для несуществующего файла, потому что это означало бы, что запрошенный ресурс не существует, а существует.
Представьте, что имена «Адам» и «Джефф» зарезервированы, но доступно любое другое имя, и на это указывает наличие файла с именем «Адам» и файла с именем «Джефф» и никаких других файлов. Эта система использует файл, чтобы указать, что имя зарезервировано. Чтобы утверждать, что отсутствующий файл не может дать 200, вы должны возразить, что мы не можем возвращать 200 для любого имени, кроме «Адам» и «Джефф».
А теперь представьте аналогичную систему, в которой все имена, кроме «Адам» и «Джефф», зарезервированы. Доступны только «Адам» и «Джефф». Эта система использует файл, чтобы указать, что имя доступно. Чтобы утверждать, что отсутствующий файл не может дать 200, вам придется снова возразить, что мы не можем возвращать 200 для любого имени, кроме «Адам» и «Джефф».
Но посмотрите, насколько странны вместе эти два результата. В обоих случаях у нас есть система, в которой люди запрашивают доступность имени. И у нас есть некоторые различия во внутренней реализации, но тем, кто запрашивает систему, они не должны знать об этом. Но наши аргументы говорят, что одна система не должна возвращать 200 для зарезервированного имени, а одна система не должна возвращать 200 для незарезервированного имени, потому что они внутренне реализуют резервирование по-разному. Это абсурдно.
Согласно стандартам это всегда должно быть 404, когда URI не отображается, см. rfc2616 раздел 10.4.5.
К сожалению, эзотерические бизнес-кейсы иногда оправдывают отступление от стандартов. С другой стороны, нарушение стандарта должно выпасть на долю команды, сделавшей необычный запрос. Вы всегда можете вернуться к тому, что «стандарты являются стандартами не зря».
Имеет ли когда-нибудь смысл для сервера предоставлять ответ 200, когда запрос GET выполняется для несуществующего файла?
На мой взгляд, любой URL-адрес, который не может завершить свою операцию (т.е. результирующий файл недействителен или не возвращается), действительно должен возвращать ошибку 5XX. Спецификация подразумевает, что ответ всегда должен отправляться с ответом 200:
200 OK - запрос выполнен. Информация вернулась ...
Это также подразумевается существованием ответа 204, который предназначен специально для запросов, которые не возвращают ответ:
204 Нет содержимого Сервер выполнил запрос, но не должен возвращать тело объекта.
Имеет ли смысл описанное поведение? Нет.
Разве ответ всегда должен быть 404?
404 кажется мне хорошим выбором ...
Сервер не нашел ничего, соответствующего Request-URI. Не указывается, является ли состояние временным или постоянным. ... Этот код состояния обычно используется, когда сервер не желает точно раскрывать, почему запрос был отклонен, или когда другой ответ не применим.
Хотя, если бы сценарий вернул 404, я все равно ожидал бы ответа в кодировке JSON размером с заголовок длины содержимого.
Не забывайте «следует ли вам» и «будет ли это работать» - это два разных вопроса. Пока потребитель веб-сайта / услуги понимает значение 0-байтового ответа, это совершенно законно. Вы можете установить код ответа на любое число от 1 до 999, вы можете изобретать новые заголовки и т. Д., Но большинство клиентов не знают, что делать с этими ответами. Несоответствие между длиной содержимого и полученным содержимым, вероятно, приведет к зависанию запросов до тех пор, пока не истечет время ожидания соединения или не будет явно закрыто.
не мой сервер / код, и определенно не существует на сервере
Описанное поведение похоже на то, что какой-то активный скрипт перехватывает URL-адрес и незаметно не может загрузить данные на его основе откуда-то (файловая система, база данных и т. Д.). Это общий шаблон для управления доступом, аналитики, кеширования и т. Д.
По сути, я думаю, что сервер отправляет заголовки ответов до фактической проверки наличия данных. Это приведет к ответу 200 без возврата данных. Короче говоря, это пахнет ошибкой / плохой практикой.
Видеть Спецификация HTTP