Говоря о внешней и внутренней маршрутизации и внешнем и внутреннем рендеринге

внешний интерфейс сервер браузер

Первоначально опубликовано мнойблог

В последнее время люди часто задают такие вопросы, как:

  • Почему приложение Vue, которое я написал, не вызывает проблем на этапе разработки, но не может быть доступно после развертывания на сервере, за исключением/страница
  • Почему маршрутизация страницы SPA, которую я написал, не вызывает проблем с использованием хэш-режима, но переход в режим истории вызывает массу проблем?
  • Что такое внешняя маршрутизация и внутренняя маршрутизация Как настроить внутреннюю часть для поддержки моей внешней маршрутизации?

Этот вопрос задают многие новички, поэтому я кратко объясню разницу и связь между ними, основываясь на своем собственном опыте обучения, в надежде помочь вам.

Ветераны могут пройти в обход и прочитать еще несколько полезных статей~

что такое маршрутизация

Понимание веб-маршрутизацииВ этой статье очень хорошо сказано.

В процессе веб-разработки часто встречается понятие «маршрутизация». Итак, что же такое маршрутизация? Проще говоря, маршрут — это сопоставление URL-адресов с функциями.

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

Из внутренней маршрутизации

В раннюю эпоху веб-разработки, в эпоху «режи-и-жечь», доминировала внутренняя маршрутизация. Будь то php, jsp или asp, большинство страниц, к которым пользователи могут получить доступ через URL-адрес, возвращаются в браузер после сопоставления с внутренней маршрутизацией. Классический вопрос на собеседовании: «Вы вводите в адресной строке браузераwww.baidu.comЧто вы испытали в процессе просмотра веб-страницы?» На самом деле это тоже правда.

В веб-бэкенде, независимо от того, на каком языке находится бэкэнд-фреймворк, будет специально разработанный модуль маршрутизации или область маршрутизации, чтобы соответствовать URL-адресу, указанному пользователем, а также некоторым адресам отправки форм и запросам ajax. Обычно встречая маршрут, который не может быть сопоставлен, серверная часть возвращает404код состояния. Это то, что мы часто говорим404 NOT FOUNDпроисхождение.

URL-адреса и методы

Если вы используете RESTful API, вы будете знакомы со следующими четырьмя типами запросов:GET,POST,PUT,DELETE.

Они соответствуют четырем основным операциям:GET используется для получения ресурсов, POST используется для создания новых ресурсов (а также может использоваться для обновления ресурсов), PUT используется для обновления ресурсов, а DELETE используется для удаления ресурсов.—— От Руан Ифэн«Понимание архитектуры RESTful»

Хотя приведенное выше является RESTful API, на самом деле, когда мы вводим URL-адрес в адресную строку и нажимаем Enter,GETзапрос отправлен. Это также означает, что URL-адрес и запрошенный метод также должны иметь однозначное соответствие. Пример приведен ниже:

router.post('/user/:id', addUser)

Если в моей внутренней конфигурации маршрутизации есть только этот маршрут. Затем я получаю доступ к нему через браузер:http://xxx.com/user/123Если он недоступен, будет возвращена ошибка 404. Поскольку задняя часть оснащена только однимpostметод маршрутизации. Если вы хотите принять этот запрос, у вас должен быть следующий маршрут:

router.get('/user/:id', getUser) // 配置get路由
router.post('/user/:id', addUser)

Внутренняя маршрутизация и рендеринг на стороне сервера

Как упоминалось ранее, в эпоху «слэш-энд-прожига» веб-страницы обычно отправляются непосредственно в клиентский браузер через внутреннюю маршрутизацию. То есть HTML-код веб-страницы обычно отображается на внутреннем сервере через механизм шаблонов, а затем передается внешнему интерфейсу. Что касается некоторых других эффектов, то за них отвечают распространенные интерфейсные фреймворки, такие как jQuery и Bootstrap, предварительно прописанные на странице.

Если вы скажете, что некоторые сайты уже реализованы через ajax, например gmail, например почтовый ящик qq. Тогда вы должны заметить, что даже для этих страниц "киль" их страниц не весь реализован через ajax, и все же бэк-энд прямо наружу - это то, о чем мы сейчас говорим.рендеринг на стороне сервера.

У рендеринга на стороне сервера есть много преимуществ, например, он оптимизирован для SEO, безопаснее использовать рендеринг на стороне сервера для некоторых страниц с высокими требованиями к безопасности. Во времена, когда в то время не было node.js, чтобы хорошо строить внешние страницы, использовался механизм шаблонов, соответствующий серверному языку, для реализации организации динамических веб-страниц, структуры страницы и повторное использование компонентов. Например, Blade в Laravel, jinja2 в Django, jsp в Struts и т. д. На самом деле, до сих пор, если серверный язык хочет реализовать свои собственные веб-функции, он должен иметь свой собственный соответствующий механизм шаблонов.

После рождения node.js стало реальностью, что интерфейс имеет собственный механизм шаблонов для внутреннего рендеринга. Обычными являются мопсы, ejs, нунджаки и т. д. Эти механизмы шаблонов в сочетании с бэкэнд-фреймворками, такими как Express и Koa, также были в моде в начале.

Однако в этом процессе, по мере того как разработка веб-приложений становится все более и более сложной, начинает постепенно вырисовываться проблема чистого рендеринга на стороне сервера — связь слишком сильна, страницы в эпоху jQuery нелегко поддерживать, и страница переключается на белый экран Серьезно подождите. Хотя проблема сцепления может быть решена за счет хорошей структуры кода и спецификаций, всем очевидно, что страницы в эпоху jQuery поддерживать непросто, глобальные переменные летают по небу, а код слишком навязчив. Последующее обслуживание обычно заключается в исправлении предыдущего кода. Хотя проблема белого экрана при переключении страниц может быть решена с помощью ajax, iframe и т. д., это проблематично в реализации, что еще больше усложняет ремонтопригодность.

Итак, мы начали вступать в эру front-end маршрутизации.

Переход на интерфейсную маршрутизацию

Внешняя маршрутизация — как следует из названия,Сопоставление правила URL для перехода на страницуУправляется фронтендом. Существует два основных метода отображения интерфейсной маршрутизации:

  • Преимущество внешней маршрутизации с хэшем заключается в высокой совместимости. Недостатком является то, что URL имеет#номер не хороший
  • Внешняя маршрутизация без хэша, преимущество в том, что URL-адрес не содержит#Нет, выглядит хорошо. Недостатком является то, что требуется поддержка как браузера, так и поддержки внутреннего сервера.

Наиболее широко используемый пример внешней маршрутизации — сегодняшний веб-проект SPA. Будь то проект страницы Vue, React или Angular, он неотделим от соответствующего инструмента маршрутизатора. Наиболее очевидным преимуществом внешней маршрутизации является то, что переход к URL-адресу в адресной строке не будет пустым экраном, что также выигрывает от преимуществ внешнего рендеринга.

Внешняя маршрутизация и внешний рендеринг

Говоря о внешней маршрутизации, мы не можем не упомянуть о внешнем рендеринге. Я беру проект Vue в качестве примера. если вы используете официальныйvue-cliЗадумывались ли вы когда-нибудь над проектом, созданным с использованием шаблона webpack, какой HTML-код получает ваш браузер? Пока ваша страницаbuttonимеютformэто похоже? Я так не думаю. В рабочем режиме вы смотрите на сборкуindex.htmlНа что это похоже:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue</title>
</head>
<body>
  <div id="app"></div>
  <script type="text/javascript" src="xxxx.xxx.js"></script>
  <script type="text/javascript" src="yyyy.yyy.js"></script>
  <script type="text/javascript" src="zzzz.zzz.js"></script>
</body>
</html>

Обычно это выглядит так. Как видите, на самом деле это html, который ваш браузер получает с сервера. Здесь только один пустой<div id="app"></div>Div этой записи и ряд файлов js, поддерживающих ее ниже. Таким образом, страница, которую вы видите, фактически отображается с помощью этих js. Это также то, что мы часто называем внешним рендерингом.

Внешний рендеринг возлагает задачу рендеринга на браузер и решает построение страницы за счет вычислительной мощности клиента, что значительно снижает нагрузку на сервер. А благодаря интерфейсной маршрутизации беспрепятственное переключение страниц становится естественным и удобным для пользователя. Однако минус в том, что он не дружественен к SEO, ведь краулер поисковой системы может сканировать только до html, как указано выше, и к версии браузера будут соответствующие требования.

Должно быть ясно, что пока вы вводите URL-адрес в адресную строку браузера и нажимаете Enter, он обязательно отправится на внутренний сервер для запроса один раз. И если это сделать, нажав кнопку на странице, обновление URL-адреса с помощью API библиотеки маршрутизатора не будет запрашиваться с внутреннего сервера.

Хэш-режим

Режим хеширования использует тот факт, что браузер не#Путь после номера инициирует запрос маршрутизации на сервер. То есть введите в браузере следующие два адреса:http://localhost/#/user/1а такжеhttp://localhost/На самом деле к серверу стоит запроситьhttp://localhostсодержание этой страницы.

И библиотека внешнего маршрутизатора захватывает#Параметры и адреса после номера используются, чтобы указать интерфейсной библиотеке (такой как Vue) отображать соответствующую страницу. Таким образом, независимо от того, входим ли мы в адресную строку браузера или переходим через API маршрутизатора на странице, используется одна и та же логика перехода. Таким образом, этот режим не требует от бэкэнда настройки другой логики, просто верните ее во фронтенд.http://localhostО соответствующем html и о том, какая страница осталась, можно судить по внешнему маршруту.

Режим истории

Без#Маршрут номера, который является формой URL, которую мы обычно видим. Библиотека маршрутизатора для реализации этой функции обычно предоставляется через HTML5.history这个api。 Напримерhistory.pushState()Вы можете нажать URL в адресную панель браузера, и этот URL не будет инициировать запрос на бэкэнду! С этой функцией могут быть легко реализованы красивые URL-адреса. Однако следует отметить, что этот API не поддерживается для браузеров IE9 и ниже, а IE10 начинает поддерживать, поэтому существуют требования для версий браузера. Vue-маршрутизатор обнаружит версию браузера и автоматически понижается в режиме HASH, когда режим истории не может быть включен.

Как упоминалось выше, ваши переходы на страницу обычно осуществляются через API маршрутизатора.Вызовы API маршрутизатора обычноhistory.pushState()Это апи, так что к бэкенду отношения не имеет. ноКак только вы введете адрес из адресной строки браузера, например,http://localhost/user/1, этот URL инициирует запрос на получение к серверной части. Если во внутренней таблице маршрутизации не настроен соответствующий маршрут, то, естественно, будет возвращена ошибка 404! Вот почему многие друзья сталкиваются с ошибкой 404 страницы в рабочем режиме.

Так много людей спросят, тогда почему я в порядке в режиме разработки? это потому, чтоvue-cliПомочь вам начаться в режиме разработкиexpressКонфигурация сервера разработки поможет вам в этом. Теоретически в режиме разработки потребовалось бы настроить сервер, толькоvue-cliВсе это настроено для вас, поэтому вам не нужно настраивать его вручную.

Итак, как его настроить? На самом деле, конфигурация в рабочем режиме также очень проста, обратитесь к той, которую дает vue-router.Пример конфигурации. Один принцип - настроить правило в конце всех внутренних правил маршрутизации.Если другие правила маршрутизации во фронте не совпадают, выполнить это правило - поставить построенное.index.htmlВернитесь на переднюю часть. Это решает проблему 404, выдаваемую внутренней маршрутизацией, потому что пока вы вводитеhttp://localhost/user/1Этот адрес, то поскольку другие маршруты на бэкенде не совпадают, он будет возвращен в браузерindex.html.

После того, как браузер получает html, библиотека маршрутизатора начинает работать, начинает получать информацию об URL-адресе адресной строки, а затем сообщает внешней библиотеке (например, Vue) об отображении соответствующей страницы. На данный момент это похоже на режим хеширования.

Конечно, поскольку серверная часть не может выдать ошибку страницы 404, правило URL-адреса 404, естественно, остается на усмотрение внешней маршрутизации. Вы можете самостоятельно решить во внешнем интерфейсе маршрутизации, какие страницы 404, которые не соответствуют ни одному URL, должны отображаться.

Внешняя маршрутизация и рендеринг на стороне сервера

Хотя внешний рендеринг имеет много преимуществ, проблема SEO по-прежнему остается относительно серьезной. Поэтому такие фреймворки, как react и vue, позже тоже приложили свои усилия для рендеринга на стороне сервера. Рендеринг на стороне сервера на основе интерфейсных библиотек отличается от предыдущего рендеринга на стороне сервера на основе внутренних языков. Большая часть рендеринга интерфейсных фреймворков на стороне сервера по-прежнему использует маршрутизацию внешнего интерфейса, и из-за введения таких концепций, как единство состояния, vnode и т. д., их рендеринг на стороне сервера требует большей производительности сервера, чем PHP и другие языки. , Требования к производительности сервера намного выше. Так что в этом плане не только сам фреймворк постоянно совершенствует алгоритмы и оптимизации, но и производительность сервера тоже должна быть улучшена. Когда Nuggets перешли на SSR, они также столкнулись с соответствующими проблемами производительности, что и послужило причиной.

Конечно, между ними также появилась концепция предварительного рендеринга. То есть часть статических html-файлов сначала создается на стороне сервера, которые используются для перехода прямо из браузера. Затем остальные страницы реализуются посредством обычного внешнего рендеринга. Обычно мы можем предварительно отрендерить домашнюю страницу. Преимущества этого очевидны, учитывая как SEO, так и требования к производительности сервера. Тем не менее, он не может достичь полного SEO сайта, а также увеличится трудоемкий этап построения производства, что также очень жаль.

Что касается предварительного рендеринга, рассмотрите возможность использованияprerender-spa-pluginЭтот плагин webapck, его версия 3.x начинает использоватьpuppeteerдля создания html-файла.

Разделение передней и задней части

Благодаря интерфейсной маршрутизации и полным возможностям внешнего и внутреннего рендеринга современных интерфейсных фреймворков, вещам, связанным с рендерингом страниц, организацией и компонентами, серверная часть, наконец, больше не может быть задействована.

Постепенно стала популярной модель разработки с разделением интерфейса и сервера. Фронтенд стал уделять больше внимания проектированию и автоматизации разработки страниц, а бэкэнд больше внимания уделял предоставлению API и гарантии баз данных. На уровне кода степень связанности еще больше снижается, а разделение труда также становится более четким. Мы также избавились от оригинальной эры веб-разработки «слэш и сжигай». Рассыпать цветы~

Суммировать

Я надеюсь, что эта статья даст вам представление о внешней и внутренней маршрутизации, а также о внешнем и внутреннем рендеринге. В реальном процессе разработки вы должны сосредоточиться не только на своей области, но и на смежных областях, чтобы легко сталкиваться с проблемами.

Примечание. Для создания рисунков в этой статье я использовал OmniGraffle. Пожалуйста, указывайте автора при перепечатке!