Как правильно обрабатывать неправильные URL-адреса (ошибки 404) в одностраничном приложении?

В настоящее время я пишу веб-приложение с использованием angularjs, но я думаю, что этот вопрос относится к любой клиентской платформе javascript, которая выполняет маршрутизацию на стороне клиента (как это делает angular).

Как правильно поступать с неправильными URL-адресами в одностраничном приложении?

Просматривая несколько крупных сайтов, я вижу, что Gmail будет перенаправлять во входящие, если вы введете любой случайный URL-адрес ниже https://mail.google.com/mail/. Это происходит на стороне сервера (с кодом http 300) или на стороне клиента, в зависимости от того, находится ли неправильный путь до или после символа #. С другой стороны, twitter показывает настоящий HTTP 404 для любого недопустимого URL. Третий вариант - показать "мягкий" 404, страницу с чисто клиентской ошибкой.

Эти решения кажутся подходящими для разных ситуаций. Твиттер хочет, чтобы ссылки на пользователей твиттера и твиты были реальными, чтобы люди могли делиться ими, публиковать их в новостных статьях и т. Д., Поэтому важно, чтобы недействительные ссылки распознавались как таковые (если у меня есть неработающая ссылка на твит в мой веб-сайт, простой сканер скажет мне это). В gmail, с другой стороны, от вас не ожидается, что вы будете делиться ссылками в своем почтовом ящике, и я даже не уверен, действительно ли ссылки являются постоянными / постоянными: кажется, что обновление URL-адреса в основном служит цели навигации по истории браузера в пределах одностраничное приложение. Третий способ выдачи мягких ошибок может быть подходящим для ситуаций, подобных gmail, но там, где нет разумной страницы "по умолчанию".

После этого длинного вступления задаются некоторые конкретные вопросы:

  • Приемлемо ли когда-либо выдавать «мягкую» страницу с ошибкой вместо ошибки 404, или одностраничное приложение всегда должно перенаправлять на настоящий 404, если URL-адрес недействителен?
  • Код Gmail может быть совершенно безошибочным, но если в нем есть ошибка, приводящая к недействительным ссылкам, которые в конечном итоге перенаправляют обратно во входящий почтовый ящик, это может сбить с толку пользователей даже больше, чем страница с ошибкой. Для большинства веб-приложений, которые не так хорошо протестированы, как Gmail, не лучше ли отображать страницу с ошибкой?
  • Чтобы реализовать настоящие 404-е для одностраничных приложений, кажется необходимым продублировать логику маршрутизации на стороне сервера. Есть ли способ обойти это?
  • При перенаправлении на 404, я думаю, пользователь должен видеть URL-адрес, вызвавший ошибку, возможно, в строке URL-адреса. Я думаю, что с помощью api истории html5 это можно сделать, просто запустив перезагрузку текущей страницы (с неправильным URL-адресом) в сочетании с маршрутизацией на стороне сервера, упомянутой выше. Для браузеров, которые не поддерживают это, или при использовании нотации hashbang, это не представляется возможным. Как лучше всего поддерживать все браузеры?

person jssebastian    schedule 08.02.2013    source источник
comment
Ваш сайт вообще работает без javascript? Вы используете history.pushState для обновления URL-адресов с помощью javascripts или сегментов в URL-адресе?   -  person Markus Unterwaditzer    schedule 08.02.2013
comment
Кроме того, почему вы говорите о перенаправлении на 404, почему бы просто не показать?   -  person Markus Unterwaditzer    schedule 08.02.2013
comment
@markus Сайт, над которым я сейчас работаю, не работает без javascript. Но я действительно хочу, чтобы внешние ссылки работали, чтобы пользователи могли делиться ссылками на сайт (обычно это делается по электронной почте). Сейчас я использую нотацию hashbang, но angularjs позволяет легко переключиться на html5 pushState, если я хочу / нужно.   -  person jssebastian    schedule 08.02.2013
comment
@MarkusUnterwaditzer: о перенаправлении и показе мягкого 404: это часть вопроса. В некоторых случаях можно показать 404-ю клиентскую сторону. Но мне нравится тот факт, что HTTP 404 имеет известную семантику, которую может понять автоматизированный инструмент (для тестирования, для проверки ссылок и т. Д.).   -  person jssebastian    schedule 08.02.2013
comment
На это нет однозначного ответа. Армин Ронахер написал статью о подходе, используемом Battlelog: сначала визуализировать сайт на стороне сервера, а затем использовать Javascript для визуализации каждого второго щелчка: lucumr.pocoo.org/2011/11/15/modern-web-applications-are-here   -  person Markus Unterwaditzer    schedule 08.02.2013
comment
В вашем случае я не думаю, что вам больше нужно заботиться о боте Google, поскольку создание вашего сайта только для javascript уже в основном исключает googlebot. Робот Google может до некоторой степени интерпретировать Javascript, но я не думаю, что бот распознал бы 404 страницы страницы, содержащей только Javascript, как таковую.   -  person Markus Unterwaditzer    schedule 08.02.2013
comment
Контент в приложении не будет виден без аутентификации, поэтому меня не волнует индексация в этом конкретном случае (как в некотором роде в примере с gmail, но с несколькими пользователями, совместно использующими почтовый ящик).   -  person jssebastian    schedule 09.02.2013
comment
Что ж, тогда в вашем случае будет достаточно просто показать сообщение с кодом 404.   -  person Markus Unterwaditzer    schedule 09.02.2013


Ответы (2)


Если вы заботитесь о поисковой оптимизации, то эту проблему можно решить с помощью angular.io (по крайней мере, с Google) - это использование метатега noindex «для обозначения статуса soft-404, который не позволит сканерам сканировать содержимое страницы». Судя по всему, это можно добавить в документ через JavaScript.

В качестве альтернативы, используя JavaScript, вы можете перенаправить на страницу, которая ответит фактическим кодом состояния HTTP 404. Google прекрасно понимает перенаправления JavaScript. Ваша исходная страница /does-not-exist при перенаправлении на /404-error?from=does-not-exist будет связана с кодом состояния 404, возвращаемым сервером. Структура URL-адреса не имеет значения, здесь важны только код состояния и перенаправление.

Другие варианты: SSR (Nuxt.js, Next.js, Angular Universal и т. Д.) Или предварительный рендеринг (prerender.io, puppeteer и т. Д.), Который Google называет динамический рендеринг, где вы отвечаете на запросы поисковых ботов с предварительно обработанной версией, в то время как пользователи-люди получают ваше обычное приложение, отрисованное на стороне клиента.

person Denis Pshenov    schedule 20.11.2018
comment
... where you respond to search bot requests with a pre-rendered version while human users get your normal client-side rendered app. Нормально ли с точки зрения SEO, если пользователь запрашивает, например, my-app.com/not-existent-path/blah/blah/blah, и мой сервер отвечает страницей, имеющей 404 код состояния HTTP, но затем после отображения страницы 404 пользователь нажимает кнопку «Перейти на домашнюю страницу», которая при нажатии изменяет только часть содержимого страницы и использует JS history API без создания нового запрос к серверу? то есть страница, отображаемая с кодом 404, после того, как приложение изменило URL-адрес через API истории. - person tonix; 29.09.2019
comment
Звучит нормально. Если вы измените URL-адрес с помощью JS History API, не имеет значения, собираетесь ли вы получать новый контент с сервера, из кеша или как-то еще - это никак не повлияет на SEO, потому что поисковые роботы не будут нажимать на вашу домашнюю страницу. в любом случае, вместо этого они сделают новый запрос к URL-адресу в этой ссылке. JS History API предназначен только для ваших друзей-пользователей. - person Denis Pshenov; 07.10.2019
comment
Для тех, кто наткнется на это, вот интересный разговор о том, как обращаться с soft-404: youtube.com/watch?v=vjj8B4sq0UI&t=30m15s (отметка 31:40 мин.). Это пресс, сделанный для конференции JavaScript fwdays, и есть интересное объяснение того, почему метатег noindex может вызывать нежелательные побочные эффекты. - person Rose; 16.05.2020
comment
@ Роуз, спасибо за видео. Честно говоря, это проблема, только если вы добавляете метатег noindex в сам ответ. Однако, если вы добавите его через JavaScript, это не должно быть проблемой. Чтобы перестраховаться, я бы не стал добавлять метатег noindex по умолчанию (как это делает angular.io), а вместо этого добавлял бы его только при необходимости. - person Denis Pshenov; 17.05.2020

tl; dr: Откажитесь от поддержки hashbang и выберите поведение, подобное PJAX, если вы заботитесь о SEO.

Вы делаете приложение или веб-сайт? Если сайту нужно вернуть 404, чтобы не запутать гугл. Это должно быть реальное 404, а не просто показывать сообщение о том, что страница не найдена (т.е. 200 с сообщением «страница не найдена» - это очень плохо). И какие браузеры вы хотите поддерживать?

Я считаю, что следует избегать всего рендеринга на стороне сервера хэшбэга (т. Е. Неприятного взлома Google SEO #!). Либо используйте реальное pushstate, либо повторно визуализируйте всю страницу, если URL-адрес изменяется для браузеров, которые не поддерживают pushstate (не изменение хэша).

Причина, по которой это имеет значение, заключается в том, что #! никогда не должен возвращать 404, потому что это не имеет смысла и невозможно имитировать серверную часть, потому что сервер никогда не получает то, что после #! без запущенного Javascript.

Таким образом, если вы действительно заботитесь о SEO, я бы сделал что-то вроде PJAX и использовал бы только true pushstate для маршрутизации, а затем просто не смог бы перейти на старую веб-версию 1.0. Следовательно, ссылки, которыми я рекомендую вам поделиться, которые действительно могут быть 404, не должны иметь #! (традиционные # подойдут до тех пор, пока содержимое страницы не изменится кардинально).

Наконец, 404 в основном не проблема, а скорее 30X, т.е. ответы перенаправления. Это потому, что браузер автоматически обрабатывает перенаправления, поэтому ваши вызовы Javascript AJAX никогда не увидят 30X (вместо этого они получат ответ перенаправления ... т.е. 200). Чтобы обрабатывать 30X ответы, вам нужно будет отправлять заголовок обратно для каждого запроса, чтобы указать, какой URL был перенаправлен (то есть, на что вы были перенаправлены), чтобы вы не испортили историю Pushstate.

Конечно, если вам нужно поддерживать хэшбанг, например, Twitter (, и именно они убили hashbang), вы можете использовать Google Sitemaps и _ 15_, чтобы попытаться снизить влияние плохого SEO.

person Adam Gent    schedule 09.02.2013
comment
PJAX выглядит интересным для тех, кто строит с нуля. Но фреймворк anuglarjs из коробки поддерживает pushState, так что я думаю, в этом нет необходимости. Или PJAX делает что-то еще? - person jssebastian; 10.02.2013
comment
Я создаю сейчас приложение, которое не будет индексироваться поисковыми системами. Но я заинтересован в более общем понимании этого вопроса. - person jssebastian; 10.02.2013
comment
Мне не было известно о проблеме с ответами pushState и 30x. Хорошо знать. Любые указатели на документы / примеры / руководства по этому поводу? - person jssebastian; 10.02.2013
comment
В частности, pjax-container концептуально выглядит так же, как angularjs ng-view. - person jssebastian; 10.02.2013