Як і чому еволюціонували сучасні рамки веб-додатків, щоб роз'єднати URL-адреси маршрутів з файлової системи?


67

Порівняно з приблизно 10 роками тому я зазначив перехід до фреймворків, використовуючи стиль маршрутизації, який відокремлює шлях URL до файлової системи. Зазвичай це здійснюється за допомогою схеми переднього контролера.

А саме, коли раніше шлях шляху до URL був відображений безпосередньо до файлової системи і, отже, відображав точні файли та папки на диску, то в даний час фактичні шляхи URL-адреси запрограмовані так, щоб вони були спрямовані на конкретні класи через конфігурацію, і, як такий, більше не відображають файл системна папка та структура файлів.

Питання

Як і чому це стало звичним явищем? Як і чому було вирішено, що "краще" до того моменту, коли колись звичайний підхід прямого до файлу фактично відмовився?

Інші відповіді

Тут є аналогічна відповідь, яка трохи вникає в поняття маршруту та деякі переваги та недоліки: чому в рамках PHP-фреймів використовується концепція "маршрут"?

Але це не стосується історичних аспектів змін, або того, як або чому ця зміна поступово сталася, до тих пір, де будь-які нові проекти в даний час в значній мірі використовують цей новий шаблон стилю маршрутизації, і прямий файл до застарілого або залишеного.

Крім того, більшість згаданих переваг та недоліків не є достатньо вагомими для того, щоб гарантувати такі глобальні зміни. Можливо, єдина користь, яку я можу побачити, як змінити цю зміну, - це приховати файлову / папкову систему від кінцевого користувача, а також її відсутність ?param=value&param2=value, що робить URL-адреси схожішими. Але чи були це єдиною причиною змін? І якщо так, то чому були ці причини цього?

Приклади:

Мені найбільше знайомі рамки PHP, і багато популярних сучасних фреймворків використовують цей розв'язаний підхід до маршрутизації. Щоб він працював, ви налаштували перезапис URL-адрес на Apache або подібний веб-сервер, де функціональність веб-додатків, як правило, більше не запускається через прямий шлях до файлу URL.

Zend Expressive

https://docs.zendframework.com/zend-expressive/features/router/aura/
https://docs.zendframework.com/zend-expressive/features/router/fast-route/
https: //docs.zendframework. com / zend-expressive / функції / маршрутизатор / zf2 /

Zend Framework

https://docs.zendframework.com/zend-mvc/routing/

Ларавель

https://laravel.com/docs/5.5/routing

CakePHP

https://book.cakephp.org/3.0/en/development/routing.html


14
чи справді була така зміна? чи, можливо, більшість мов / фреймворків ніколи не використовували пряме відображення файлової системи? можливо, це просто PHP, що наздоганяє решту здорових? ваші спостереження, на мій погляд, неправильні, тому немає хорошої відповіді. також "зсув", який ви згадуєте, відбувся лише у світі PHP. але це занадто широке питання на мій погляд ...
rsm

2
@rsm У мене була подібна перша реакція, але при подальшій думці, це дійсно те, що було зроблено на багатьох мовах та платформах, що призводить до того, що вона є дійсно поширеним джерелом вразливих місць.
JimmyJames

6
@rsm, це може бути більш очевидним у структурах PHP, але використовувати інший спосіб - за певний час, перш ніж будь-який фреймворк дійсно захопився, будь то ASP, .NET, PHP, JSP тощо, в Інтернеті здебільшого використовується прямо- підхід до файлів. Чому всі ці рамки були розроблені для використання розв'язаного підходу? У технічному плані підхід прямого до файлу все ще можливий, і я впевнений, що сучасні рамки можуть його використовувати. Або вони можуть? Можливо, вони не можуть, і, можливо, є вагомі причини, чому вони цього не роблять? Якими були б ці причини ..? Вони навіть не надають спосіб або плагін для цього, вони просто викорінили прямий файл у файл.
Денніс

2
Хіба це (частково) не стосується також перегляду URL-адреси ( локатора , як знайти ресурс) як URI (та ідентифікатора )?
Хаген фон Ейтцен

2
Пов’язане читання з античної історії: Прохолодні URI не змінюються - Тім Бернерс-Лі, 1998
Майкл Хемптон

Відповіді:


72

У своїй найпростішій формі веб-сайт подає статичні файли. Зображення шляху URL до шляху до файлу є найбільш очевидним вибором; по суті, це FTP-сайт, доступний лише для читання.

Тоді люди хотіли змінити вміст сторінки деяким сценарієм. Найпростіший спосіб - вставити мову сценарію на сторінку та запустити її через перекладача. Знову ж таки, враховуючи вже існуючу траєкторію шляху до файлу>, це було досить просто.

Але насправді ви зараз запускаєте цей файл як аргумент для перекладача. Ви повинні визначити, коли запит є статичним файлом, а коли - тим, що вам потрібно інтерпретувати.

Як тільки ви почнете використовувати більш досконалі компільовані мови, ви ще більше розлучитеся з розташуванням файлу.

Крім того, ваш веб-сервер вже кешує статичні файли і робить всілякі оптимізації, це означає, що потрапляння на файлову систему - це виняток, а не правило. На даний момент шлях до старої файлової системи посилань є скоріше перешкодою, ніж допомогою.

Але я думаю, що справжня зміна моря настала, коли користувачі хотіли позбутися розширення файлу зі шляху. Отримати myPage.asp або myPage.php було щось, що бентежило «нормальних» людей і заважало SEO.

Оскільки користувач бачить шлях, він став частиною інтерфейсу Інтернету, і тому він повинен бути повністю звільнений від будь-яких технічних обмежень. Ми втратили "www" і практично все є ".com". Кілька URL-адрес будуть вказувати на одну і ту ж сторінку.

Якщо я заробляю більше грошей за допомогою mydomain.com/sale vs www.mydomain.co.uk/products/sale.aspx, я не хочу, щоб якісь технічні обмеження не заважали мені.


7
Я завжди думав, що бажання приховати розширення файлів частково було "безпекою через неясність" - трохи ускладнюючи інформацію про те, якою технологією користується сайт, щоб зробити його менш легким для націлювання на конкретні додані / відомі подвиги певних серверів та техніка на той час
Caius Jard

20
@CaiusJard, що є частиною цього, але інша частина - це агностицизм технологій - замінивши file.html на наших шляхах, ми не хотіли пізніше застрягнути іншим комутатором (наприклад, file.phtml у file.php або навіть у file.asp). Але оскільки ми роз'єднуємо шлях до URL-адрес та файлової системи (використовуючи маршрутизацію чи будь-що інше) для доступу до ресурсів, побудованих із записів бази даних та / або інших джерел, навіщо взагалі мати розширення в URL-адресі?
HorusKol

39
@HorusKol Технологія не просто стосується того, щоб змінювати всі файли на своєму шляху. Можливість змінити бекенд-технології, не порушуючи робочого процесу та закладок вашого клієнта та не руйнуючи SEO, може бути величезною .
Шейн

7
Цікаво, що ніколи не рекомендували мати в URI розширення імен файлів, тому вони мали бути вилучені з файлової системи на початку. Найбільш раннє посилання, яке я можу знайти для цього, є з 1998 року , що фактично передує більшості розробок, описаних у цій відповіді.
Конрад Рудольф

8
За старих часів mydomain.com/sale ще працював; він перенаправлений на / продаж / та завантажений просто (ваша сторінка була mydomain.com/sale/index.aspx, але ніхто не бачив index.aspx).
Джошуа

39

Ви можете ознайомитись з білою книгою Роя Філдінга про представницький переклад стану (REST) щодо того, коли і чому . Перший фреймворк, який мені знав про те, що розрізняв ресурс і файл, був Ruby on Rails - вводив концепцію URL в маршрутизацію коду.

Основними поняттями REST, які були трансформаційними:

  • URL-адреса представляє ресурс
  • Цей ресурс може мати декілька представлень
  • URL-адреса не повинна зламатися, якщо програма реструктуризована
  • Програми повинні охоплювати без громадянства Інтернет

Основним недоліком наявності файлів, які подаються безпосередньо за URL-адресою, є те, що у вас виникають такі проблеми:

  • Посилання на ресурси постійно порушуються під час реорганізації веб-сайтів
  • Ресурс та представництво пов'язані між собою

Я думаю, що важливо також забезпечити справедливий баланс:

  • Не всі ресурси мають однакове значення. Ось чому у вас все ще доступні ресурси на основі стилів (CSS, JavaScript / EcmaScript, зображення)
  • Є вдосконалення REST на зразок HATEOAS, які краще підтримують додатки для однієї сторінки.

коли ви говорите про представлення, ви маєте на увазі такі речі, як JSON / HTML / TEXT / тощо? Я смутно знайомий з REST, але я думаю , навіть з REST ви повинні мати якийсь - то тригер , щоб змінити уявлення відповіді ...
Dennis

@Dennis, так. HTTP має ряд заголовків, за допомогою яких можна натякнути на потрібну форму ( developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation ), а REST все стосувався використання сильних сторін HTTP. Однак, все ще не рідкість у додатку є власний спосіб узгодження потрібного вмісту.
Берин Лорич

5
CGI (1993), Servlets (1997) та JSP (1999) часто від'єднують URL-адреси від файлової системи та попередньо REST (2000). Однак ця відповідь в основному правильна при визначенні причин популярності дизайнерського шаблону: REST, Java Struts і Ruby on Rails мають величезний вплив на популярність 21-го століття відокремлення ресурсів від представництва.
1818

1
Згідно з документом Філдінга, "Перше видання REST було розроблено в період з жовтня 1994 р. По серпень 1995 р."
Коннор

1
@dcorking, CGI на той час не розв'язував URL-адреси з файлів, він просто запускав файл, а не 9 разів з 10. Сервлети можуть бути найближчим співвідношенням, але якщо ви говорите про концепцію маршрутів та маєте призначений простір для URL-адреси. , що поставляється із рейками та подібними рамками.
Берін Лорич

20

Я не думаю, що це артефакт сучасних рамок веб-додатків, це, в основному, артефакт динамічного розміщення сторінок загалом.

За старих часів існували в основному статичні веб-сторінки, де програмне забезпечення подало окремі файли з файлової системи своїм шляхом. Вони зробили це здебільшого тому, що відображення 1: 1 відображення шляхів до файлових системних шляхів (з одним каталогом, позначеним як веб-корінь) було очевидним вибором, хоча переписування URL-адрес (наприклад, для переспрямування після переміщення файлів) також було поширеним.

Потім настав вік подачі динамічного контенту. Сценарії CGI (і все, що розвивалося з них) справді створювали сторінки з льоту, підтримуючи якусь базу даних. Параметри GET в URL-адресі стали звичайними, наприклад en.wikipedia.org/w/index.php?title=Path_(computing) .

Однак зручніше мати читабельну URL-адресу, що складається лише з сегментів шляху. Тож динамічні програми відображають прості шляхи (наприклад, en.wikipedia.org/wiki/Path_(computing) ) до параметрів, і ці відображення відомі як "маршрути".

Можливо, цей підхід відчувається останнім часом, оскільки він набув популярності, коли важливість юзабіліті була визнана ширше, а також стала частиною SEO. Це, мабуть, причина, чому він був вбудований безпосередньо у великі веб-рамки.


12

Однією з причин є те, що завантаження файлу з диска на кожен запит відбувається повільно, тому веб-сервери почали створювати способи кешування файлів у пам'яті, то якщо ви все одно намагаєтесь зберегти його в пам'яті, чому це важливо, де він був диск?

Однією з причин є те, що багато веб-фреймворків написані на компільованих мовах, тому у вас навіть на диску немає файлової структури, а лише jarфайлу чи будь-якого іншого. Інтерпретовані мови запозичили ідеї, які їм сподобалися, зі складених.

Однією з причин є прагнення до більш семантичних, динамічних маршрутів, наприклад https://softwareengineering.stackexchange.com/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes. Очевидно, ви не хочете /var/www/questions/363517/how-and-why-did-modern-web-application-frameworks-evolve-to-decouple-url-routes.phpфайлу. Ви використовували правила переписування URL-адрес у конфігурації веб-сервера для створення таких маршрутів. Тепер це просто зміна коду, що набагато простіше в експлуатації.


Для цього прикладу не потрібно переписувати URL-адреси.
Yay295

1
Він обробляється кодом, який розпізнає першу частину шляху, і використовує номер / 363517 / для пошуку питання в базі даних. Нічого спільного з самим веб-сервером, але з додатком ...
Буде Кроуфорд

11

З найважливіших причин, ймовірно, що такий підхід відображення URI до шляхів файлів призвів до великої кількості випадкових випусків даних через File Path Traversal

Коли ви відображаєте шлях до файлової системи, це означає, що вам потрібно перевірити, чи кожен шлях, який ви отримуєте як запит, відображається на файли, які повинні бути доступні клієнтам. Простий підхід до гарантії, що цього не відбувається, - це усунути прозоре відображення та зробити це більш чітко.

Це не лише проблема PHP. Як доказ тут наводимо відповідний розділ керівництва про загартовування Apache .


1
Чому потік?
JimmyJames

8

Я не можу відповісти за галузь, але можу сказати, чому я відійшов від URL = файлової системи ще на початку 2000-х років у напрямку віртуальних «маршрутів».

Робота з PHP 'old school', якщо у вас 1000 сторінок PHP, у вас буде 1000 файлів PHP, що представляють ці сторінки. Кожен дублюючий заголовок / колонтитул включає, можливо, і якусь іншу логіку. Тепер скажемо, що вам потрібно це змінити. Який безлад тепер у вас на руках! Вам або доведеться змінити всі 1000 файлів, або у вас в результаті з'являється дуже некрасивий код у верхньому колонтитулі, щоб обробити всі випадки. Використовуючи віртуальні маршрути, логіка заголовка / колонтитула, логіка підключення до бази даних та інша ініціалізація включаються один раз , період. Набагато краще працювати.

Ще одна причина - уникнути неоднозначності. У міру зростання додатків заголовки та колонтитули, які включаються, стають складнішими. Зазвичай вони вкладали власні, які залежали від різних речей. У файлі PHP 'сторінки' часто виникають неоднозначності щодо того, чи є змінною isset () чи ні. Використовуючи віртуальні маршрути та додаток, де все необхідне завантажується на кожній сторінці завантаження, у вас більше немає такої турботи.

Нарешті (хоча є й інші причини, але це останній список), багато з цих 1000 сторінок представляють код, який буде дублюватися. Тож після рефакторингу на належний набір класів та шаблонів код значно спрощується, і ви можете робити все, що завгодно, не маючи цих 1000 файлів.


Ви можете сказати більше, чому б у вас опинився дуже некрасивий код? Я можу побачити необхідність зміни 1000 файлів (якщо припустити, що це оновлення заголовка / колонтитула включає), але що ви маєте на увазі під підстрибуванням некрасивого коду?
Денніс

Дивіться параграф, який я щойно додав. Але в основному, по мірі розширення коду заголовка / колонтитулу / ініціалізації на обробку більшої кількості випадків, особливо якщо ви умовно включаєте інші файли (це було поганою звичкою, але це зробили багато програмістів PHP), у вас виявляється дуже важко слідувати коду .
GrandmasterB

5

Я не буду надто детально розповідати про те, чому це розлука вигідна. Основний аргумент полягає в тому, що він відокремлює семантику (до чого ви насправді намагаєтесь отримати доступ) від основної реалізації.

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

Принаймні, з мого досвіду, спочатку це часто робилося через конфігурацію Apache - і, імовірно, інші веб-сервери також підтримували це. Однак концептуально немає вагомих причин, чому сервер повинен мати на це завдання. Зрештою, маршрути є специфічними для фактичного застосування, тому є сенс визначити їх там.

Це змінилося глобально, але, як ви зазначаєте, поступово. Причина цього майже напевно дуже проста: хороші ідеї поширюються з часом. Це також є причиною, що зміни не відбулися в усьому світі. Справа не в тому, що всі зібралися і вирішили це зробити так. Радше, кожен проект адаптував такий підхід, коли вважав, що це буде вигідним (а проекти, які його не підтримували, зрештою зникли).


1

RFC вже будували концепції з нуля, з URI (які не прикріплювали жодної семантики до локальної частини) та URL-адреси як особливий випадок, який запровадив семантику, що нагадує шлях, щоб HTML-документи могли використовувати посилання відносно документа базова URL-адреса.

Очевидно, що реалізація полягає в тому, щоб відобразити локальну частину URL-адреси безпосередньо у файловій системі, тому це робилося простими налаштуваннями - чи використовуєте ви спеціалізовану реляційну базу даних для пошуку документа, або скористаєтесь високооптимізованим низьким накладним ключем -цінні магазини, які ви вже маєте, не мають значення зовні, але, безумовно, впливають на структуру витрат на обслуговування документів.

Якщо у вас є веб-додаток із постійними даними, ця структура витрат змінюється: у вас завжди є накладні витрати на запуск програми, а інтеграція розшифровки URL-адрес у неї полегшує реалізацію багатьох функцій, зменшуючи витрати.


1

На початку часу URL-адреси відображалися безпосередньо на шляху до файлів на сервері, тому що це просто, і іншого способу це зробити все одно, чи не так? Якщо я попрошу /path/to/index.php, я /path/to/index.phpрозпочну з кореневого каталогу веб-сайту (як правило, не самого сервера, веб-сайт повинен зберігатися в каталозі або підкаталозі далі).

Потім через пару років ми почали вивчати переписування, що обслуговує інший ресурс, ніж той, про який, мабуть, вимагали. /request/path/to/index.phpнасправді може служити /response/path/to/index.php.

Ще одна хитрість - це приховування index.php. Якщо я попрошу, щоб /index.php?foo=bar&baz=quxсервер міг відповісти, сховавшись index.phpтак:, /?foo=bar&baz=quxвесь час насправді обслуговуючи index.phpвсе одно.

Наступним кроком, який є важливим, є те, що ми навчилися перенаправляти всі URL-адреси /index.php. Тож тепер /path/to/some/pageмовчки перенаправляється на /index.php?path/to/some/page. Це дещо складно, тому що зазвичай кожна коса риса являє собою новий підкаталог, але в цьому випадку веб-сервер налаштований на те, щоб відправити шлях як параметр, а не шукати його.

Тепер, коли ми маємо це, нам потрібен зовсім інший спосіб мислення про те, як організовано веб-сайт. Раніше це була нещільна колекція різних сторінок. Тепер все направляється через одну вхідну сторінку. Це робить сайт набагато складнішим, але надає можливості, які раніше були недоступні, такі як аутентифікація користувачів на всьому сайті, рівномірне застосування заголовків, колонтитулів та стилів тощо.

Це фактично перетворює ваш сто або тисячу веб-сайтів додатків (якщо ви вважаєте кожен файл своїм додатком) в єдине, набагато складніше, але набагато більш послідовне додаток.

Це величезний стрибок, оскільки ви вже не можете сказати, який код буде виконуватися, просто переглянувши URL-адресу. Тепер вам потрібно глибоко зрозуміти, як ваш конкретний фреймворк переводить URL-шляхи в кодові шляхи, і хоча існують подібності між рамками, більшість є досить різними, що вам потрібно певне ознайомлення, щоб мати можливість працювати з кодом.

Коротше кажучи, це було поступовою еволюцією відкриття, а не раптовим стрибком, і кожному розробнику в значній мірі довелося пройти той самий шлях відкриття. Крива навчання досить крута, якщо тільки ви не зможете зрозуміти абстрактні поняття дуже швидко.


-1

Як давній webdev, я вважаю, що поява без історічного навігаційного контролю ( history.pushState()) в часи HTML5 зробила це практичним. Перед цим вам довелося перезавантажити сторінку, щоб оновити рядок URL-адрес, якщо тільки ви не оновили лише фрагмент ( /path#fragment). Цей фрагмент був невидимий для сервера (він не маршрутизований), тому єдиним способом оновлення або закладки динамічної сторінки було використання JavaScript.

Це має великі наслідки для SEO, і змусило Google розробити рідко використовувану схему "хешбанг", для якої потрібне відображення на динамічних хешах фізичних URL-адрес на стороні сервера. Це було непростим і не універсальним серед роботів, що веде (помилкову) аксіому: "павуки не можуть повзати вміст аякса". Але переваги вмісту ajax є відчутними: спробуйте скористатися, наприклад, картами Google без JS.

Рішення було способом оновити рядок URL-адреси значенням, яке можна відобразити на сервері (дозволяючи закладки та не оновлюючи JS), БЕЗ перезавантаження сторінки. Після того, як ця можливість була доступна, розробники могли "орієнтуватися" на сайті, просто оновивши "основний розділ вмісту", URL-адресу та сухарі. Це означало, що всі JS + CSS не потребували перевстановлення + розбору, що дозволить ВЕЛИЧЕ швидше перенести сторінку на сторінку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.