Я создаю одностраничное приложение AJAX и хотел бы при определенных обстоятельствах сохранять состояние в JSON после хэша URL-адреса (#). Я видел пару других сайтов, делающих это, но я надеюсь получить некоторые передовые практики, советы или ошибки, когда я работаю над реализацией этого.

5
DuckMaestro 16 Мар 2011 в 02:48
Другие сайты, похоже, обходятся без кодировки base64, но мне интересно, ограничили ли они себя каким-либо образом или же проблемы с совместимостью или синтаксическим анализом.
 – 
DuckMaestro
16 Мар 2011 в 04:11

2 ответа

Лучший ответ

Возвращаясь к ответу на свой вопрос - я могу засвидетельствовать, что кодирование URL (хотя бы частично) строки JSON отлично работает в нашей производственной среде.

Бывший. исходный JSON:

{"mode":21,"popup":18,"windowId":2}

Бывший. закодировано в URL:

http://example.com/my-ajax-app#%7B%22mode%22:21,%22popup%22:18,%22windowId%22:2%7D

Для небольших объемов JSON, таких как указано выше, у нас не было проблем ни в одном браузере (даже в IE7). Строки JSON большего размера мы не тестировали.

5
DuckMaestro 18 Июл 2012 в 09:06
+1 Я планирую использовать ту же технику, спасибо, что поделились своим опытом
 – 
Christophe
29 Сен 2012 в 06:27
Должен сказать, выглядит не очень красиво.
 – 
Kevin Dice
14 Авг 2015 в 18:54

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

В качестве лучшей альтернативы я бы посоветовал использовать x-www-form-urlencoded в качестве инкапсуляции. Например, если это ваш объект состояния:

var stateObject = {
  userName: 'John Doe',
  age: 31
}

Затем вы должны создать такой хеш-фрагмент:

// Create an array to build the output string.
var hashPartBuffer = [];
for (var k in stateObject) {
  hashPartBuffer.push(
    encodeURIComponent(k),
    '=',
    encodeURIComponent(stateObject[k]),
    '&'); 
}
if (hashPartBuffer.length) {
  // Remove the last element from the string buffer
  // which is '&'.
  hashPartBuffer.pop();
}
var hashPartString = hashPartBuffer.join('');
// This will now be 'userName=John%20Doe&age=31'

Затем вы снова проанализируете это:

var hashPartString = 'userName=John%20Doe&age=31';
var pairs = hashPartString.split(/&/);
var stateObject = {};
for (var i = 0; i < pairs.length; i++) {
  var keyValue = pairs.split(/=/);
  // Validate that this has the right structure.
  if (keyValue.length == 2) {
    stateObject[keyValue[0]] = keyValue[1];
  }
}
8
Sorin Mocanu 18 Мар 2011 в 23:29
Спасибо за ответ. Однако я использую популярную библиотеку json2.js для старых браузеров и собственный объект JSON в новых браузерах. Так что просто с точки зрения безопасности, я считаю, что JSON является нормальным явлением.
 – 
DuckMaestro
19 Мар 2011 в 06:31
2
Опечатка в коде, декодирующем строку. Вместо var keyValue = pairs.split(/=/); должно быть var keyValue = pairs[i].split(/=/);
 – 
Mikhail Fiadosenka
9 Окт 2012 в 18:11
В дополнение к исправлению, предложенному Михаилом Фидосенко, разве вы не хотите использовать decodeURIComponent для ключей и значений, поскольку вы их изначально закодировали? stateObject[decodeURIComponent(keyValue[0])] = decodeURIComponent(keyValue[1]);
 – 
Sam Fen
9 Дек 2016 в 22:24