history.pushState Взаимодействие URL с загрузкой jquery, приводящей к ошибке выборки страницы? - PullRequest
0 голосов
/ 09 января 2020

Я использую history.pushState , чтобы установить URL, и в то же время использую jquery .load для фактической загрузки содержимого страницы. Я новичок в истории API, но я понимаю, что это нормальный способ получить функциональность back-button / et c в динамических c сайтах.

Проблема в том, что подделанный адрес I Настройка с pushState используется .load в некотором роде, когда он выбирает страницы, что означает, что .load пытается извлечь несуществующие страницы, и поэтому не удается. DocumentRoot находится на /var/www/bar на сервере. В этом примере пользователь пытается перемещаться между двумя точками в одном файле html на сервере, который расположен в dir1/dir2/p1.html в DocumentRoot на сервере.

  1. Когда пользователь нажимает на ссылку 1, сервер должен возвращать dir1/dir2/p1.html #Container1, а в адресной строке должно отображаться foo.com/a/b/c
  2. Когда пользователь нажимает на ссылку 2, сервер должен вернуть dir1/dir2/p1.html #Container2, а в адресной строке должно появиться foo.com/a/b/d

Так как именно мне это сделать? Это то, что я пробовал с относительными URL-адресами, и это терпит неудачу:

$("#mainContent").load("dir1/dir2/p1.html #container1");  // good: XHR fetch foo.com/bar/dir1/dir2/p1.html
history.pushState(null, null, "a/b/c");                   // good: shows 'foo.com/a/b/c' as the URL
...
$("#mainContent").load("dir1/dir2/p1.html #container2");  // bad: XHR fetch foo.com/bar/a/b/dir1/dir2/p1.html
history.pushState(null, null, "a/b/d");                   // bad: shows 'foo.com/a/b/a/b/d' as the URL

И вот что происходит, когда я использую абсолютные URL-адреса:

$("#mainContent").load("/dir1/dir2/p1.html #container1");  // good: XHR fetch foo.com/bar/dir1/dir2/p1.html
history.pushState(null, null, "a/b/c");                    // good: shows 'foo.com/a/b/c' as the URL
...
$("#mainContent").load("/dir1/dir2/p1.html #container2");  // bad: XHR fetch foo.com/a/b/dir1/dir2/p1.html
history.pushState(null, null, "a/b/d");                    // good: shows 'foo.com/a/b/d' as the URL

Обратите внимание, что абсолютные пути еще хуже то, что в выборках XHR даже больше не используется DocumentRoot (bar). Спасибо.

РЕДАКТИРОВАТЬ 1

относительный случай, протестированный на Chrome / Windows и Firefox / Linux с теми же результатами; абсолютный случай проверен только на Firefox / Linux.

РЕДАКТИРОВАТЬ 2

Я экспериментировал и нашел два способа исправить это, но я не очень Понять, что происходит, поэтому я не буду публиковать это как ответ:

  1. Сохраняйте все URL-адреса, установленные history, на глубину одного уровня, поэтому a/b/c становится a-b-c. Все, что я гуглил по API истории, показывает только URL-адреса одного уровня, так что, возможно, это обычное
  2. Добавление тега base к <head> (<base "href=http://example.com/" target="_blank">

1 Ответ

1 голос
/ 20 января 2020

Изменение состояния истории изменит документ URL и, следовательно, baseURI, если нет других вещей, которые уже изменили его, например, <base> элемент.

Таким образом, все будущие сетевые запросы будут действительно выполняться с этого нового базового URI.

Чтобы обойти это, вы можете вручную сбросить baseURI после изменения состояния истории,

console.log( document.baseURI ); // /js

history.pushState(null, null, '/foo');
console.log( document.baseURI ); // /foo

// manually set document's baseURI via <base>
const base = document.createElement('base');
base.href = 'bar';
document.head.append(base);
console.log( document.baseURI ); // /bar

В качестве jsfiddle для пользователей, сталкивающихся с нулевыми ограничениями iframes StackSnippet

Или вы можете просто добавить этот элемент один раз в документ с первой страницы загрузки.

...