#javascript #json #cookies #encoding
#javascript #json #файлы cookie #кодирование
Вопрос:
В частности, при сохранении JSON в cookie безопасно ли просто сохранять исходное значение?
Причина, по которой я не хочу кодировать, заключается в том, что json имеет небольшие значения и ключи, но сложную структуру, поэтому кодирование, заменяющее все «, : и {}, значительно увеличивает длину строки
Ответ №1:
если ваши значения содержат «символы JSON» (например, запятую, кавычки, [] и т.д.), То вам, вероятно, следует использовать encodeURIComponent, чтобы они экранировались и не нарушали ваш код при чтении значений обратно.
Комментарии:
1. Но исходный файл cookie, написанный кодом на стороне сервера, не защищен и ничего не нарушает
Ответ №2:
Вы можете преобразовать свой объект JSON в строку, используя метод JSON.stringify(), а затем сохранить его в файле cookie.
Обратите внимание, что файлы cookie имеют ограничение в 4000 символов.
Если ваша строка Json допустима, не должно быть необходимости ее кодировать.
например
JSON.stringify({a:'foo"bar"',bar:69});
=> '{"a":"foo"bar"","bar":69}'
допустимые значения json экранируются.
Комментарии:
1. Я уже делаю это (чтобы быть педантичным, json технически является именем строки, возвращаемой JSON.stringify()) — вопрос в том, безопасно ли записывать json как cookie без экранирования специальных символов
2. JSON.stringify автоматически экранирует символы по мере необходимости. как вы можете получить допустимую строку json, не экранируя ее в первую очередь?
3. Я думаю, вы, возможно, путаете escaped («»») и encoded («% 22»)
4. herostwist amp; @whererhys: encodeURIComponent будет кодировать символы, которые не нужно кодировать, true. Но он также будет кодировать символы, которые действительно нужно кодировать, например, точки с запятой (возможно, другие символы, такие как пробел, также могут быть проблематичными в файлах cookie). Поскольку вам все равно приходится декодировать на сервере, если значение содержит точки с запятой, и это встроенная функция, это очевидный выбор.
5. Это плохой совет, если вы не уверены на 100%, что ваш объект JSON никогда не будет содержать точки с запятой. Использование encodeURIComponent() намного безопаснее…
Ответ №3:
Это очень хорошо задокументировано в MDN
Чтобы избежать неожиданных запросов к серверу, вам следует вызывать encodeURIComponent для любых введенных пользователем параметров, которые будут переданы как часть URI. Например, пользователь может ввести «Thyme amp; time =again» для комментария к переменной. Если не использовать encodeURIComponent для этой переменной, то снова будет получен комментарий = Thyme amp; time = . Обратите внимание, что амперсанд и знак равенства обозначают новую пару ключ-значение. Таким образом, вместо ключа комментария к публикации, равного «Thyme amp; time =again», у вас есть два ключа POST, один из которых равен «Thyme», а другой (time) равен again.
Комментарии:
1. Вопрос касается файлов cookie, а не URL-адресов.
Ответ №4:
Если вы не можете быть уверены, что ваш JSON не будет содержать зарезервированных символов, таких как ;
, тогда вам захочется выполнить экранирование для любых строк, хранящихся в cookie. RFC 6265 охватывает специальные символы, которые недопустимы в имени файла cookie или значении файла cookie.
Если вы кодируете статический контент, которым управляете, то это экранирование может оказаться ненужным. Если вы кодируете динамический контент, такой как кодирование пользовательского контента, вам, вероятно, потребуется экранирование.
MDN рекомендует использовать encodeURIComponent для экранирования любых запрещенных символов.
Вы можете использовать библиотеку, такую как cookie, чтобы справиться с этим за вас, но если ваш сервер написан на другом языке, вам нужно будет убедиться, что он использует библиотеку или языковые утилиты для кодирования компонента при установке файлов cookie и для декодирования компонента при чтении файлов cookie.
JSON.stringify
недостаточно, как показано на этом тривиальном примере:
const bio = JSON.stringify({ "description": "foo; bar; baz" });
document.cookie = `bio=${stringified}`;
// Notice that the content after the first `;` is dropped.
// Attempting to JSON.parse this later will fail.
console.log(document.cookie) // bio={"description":"foo;
Ответ №5:
Файл cookie: name=значение; name2=значение2
Пробелы являются частью разделения файлов cookie в заголовке HTTP Cookie. Необработанные пробелы в значениях файлов cookie могут, таким образом, сбить сервер с толку.