Альтернатива строке запроса и файлам cookie при отправке данных на сервер?

У меня есть небольшая (или, возможно, не такая уж маленькая) проблема с некоторыми сайтами ASP.NET/Castle Monorail для продукта, над которым я работаю. Это довольно устаревшая система (написанная задолго до меня), и она использует запросы GET со значительным объемом информации в строке запроса. Недавно мы столкнулись с ограничениями длины строки запроса, и для объема данных, которые нам нужно передать на сервер, временное хранение данных в файле cookie также неправдоподобно (мы уже преодолели ограничение в 4096 байт на файл cookie, и мы установить много файлов cookie, поэтому мы, вероятно, также приближаемся к пределу файлов cookie для каждого домена.)

Мне интересно, есть ли какие-либо альтернативы, кроме POST (в некоторых случаях возможен переход на запрос POST, но, вероятно, не во всех), которые могут решить эту проблему. Я надеюсь, что кто-то еще здесь, в StackOverflow, сталкивался с подобными проблемами и имеет какое-то волшебное решение (например, сжимать данные с помощью javascript, кодировать как base64, переходить к одному элементу строки запроса? Просто не уверен, есть ли какие-либо библиотеки, которые могут сжимать данные с помощью javascript, совместимым со встроенными классами сжатия в .NET 3.5.)

ОБНОВИТЬ:

В итоге я выбрал решение POST на временный контроллер. Этот временный контроллер вытащил большой список данных, поместил его в общий сеанс (рабочие серверы находятся в большой ферме серверов с несколькими банками, которая не использует фиксированные сеансы/IP-адреса) и выполнил GET для фактического контроллера, который вытащил данные из общего сеанса. Не самое эффективное решение, но оно решило проблему.


person jrista    schedule 28.07.2009    source источник
comment
Пожалуйста, объясните, почему вы не можете POST. Единственное реальное решение здесь, ИМХО, - это POSTing.   -  person Mauricio Scheffer    schedule 28.07.2009
comment
Имеет смысл использовать POST, так что используйте его.   -  person Josh Stodola    schedule 28.07.2009
comment
Код, с которым я работаю, в конечном счете является оболочкой гораздо более старого кода, написанного на объектах VB6 и COM. В тех случаях, когда это просто новый код, POST может быть вариантом ... в случаях, когда это просто очень старый устаревший код, реализация POST займет гораздо больше времени, чем мне нужно исправить и доставить.   -  person jrista    schedule 28.07.2009
comment
Почему это займет больше времени? Это просто метод!   -  person Josh Stodola    schedule 28.07.2009
comment
Я согласен с Джошем. Если это приложение Monorail, то Monorail отвечает за обработку веб-запросов, и вы можете легко изменить GET на POST.   -  person Mauricio Scheffer    schedule 28.07.2009
comment
@Josh: Многие из устаревших страниц изначально принимают POST, выполняют переадресацию 302, которые затем выполняют GET на других страницах и т. д. и т. д. Это очень уродливый беспорядок, но просто переключить тип запроса с GET на POST в этом случае не получится. не так просто, как может показаться. :(   -  person jrista    schedule 29.07.2009


Ответы (7)


Существует несколько плагинов кодирования Base64 для jQuery, но это не так. Помогите, потому что Base64 обычно делает данные длиннее, а не короче.

В зависимости от данных я бы рассмотрел некоторые другие методы сжатия текста. Википедия перечисляет несколько:

  • Метод взвешивания контекстного дерева (CTW)
  • Преобразование Берроуза-Уилера (предварительная обработка блочной сортировки, которая делает сжатие более эффективным)
  • LZ77 (используется DEFLATE)
  • ЛЗВ

Вот реализация LZW для Javascript.

Кодировка Хаффмана основана на частоте букв, поэтому она может не подходить для ваших данных. Вам, вероятно, придется экранировать результат, чтобы сделать его безопасным для URL.

person Jon Galloway    schedule 28.07.2009
comment
Знаете ли вы какие-либо алгоритмы сжатия для javascript или jQuery? Я могу найти другую кодировку, это сжатие, которое меня действительно интересует... - person jrista; 28.07.2009
comment
Это rumkin.com/tools/compression/compress_huff.php. Вы можете увидеть код, если посмотрите исходный код. - person John Fisher; 28.07.2009
comment
Джон, я уже связался с этим (см. ссылку для кодировки Хаффмана). Следует иметь в виду, что Хаффман работает со стандартными частотами символов в английском языке, поэтому, если ваши данные формы не являются английским текстом, это может быть не очень эффективно. - person Jon Galloway; 28.07.2009

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

person John Rasch    schedule 28.07.2009
comment
Ajax может быть возможностью в некоторых случаях. Проблема в том, что существует довольно много страниц, на которых есть проблема, и каждая из них имеет разные требования. Спасибо за напоминание о base64... Я всегда забываю, что он удваивает размер данных. вздох - person jrista; 28.07.2009

Я бы предложил использовать JSON в качестве формата передачи данных, если массив, подобный строке запроса, генерируется следующим образом:

params[]=sth&params[]=sth2&params[]=sth3

Это было бы

{params:['sth1', 'sth2', 'sth3']}

Вы можете назначить эту строку JSON однобуквенной переменной, как показано ниже.

p={params:['sth1', 'sth2', 'sth3']}

Еще лучше было бы сжать и закодировать в Base64 всю строку запроса. Поскольку вы генерируете строку запроса на стороне сервера (я предполагаю, что то же самое можно сделать в JS, используя те же алгоритмы компоновки/декомпрессии), вы можете использовать любой встроенный алгоритм сжатия с вашим языком программирования, например gzip. После того, как Base64 кодирует сжатые данные, да, они немного расширятся, но не так сильно, как кодирование URL-адресов.

person BYK    schedule 28.07.2009
comment
Спасибо за нестандартную идею (это то, что я искал... нестандартные идеи). Преобразование данных в JSON экономит небольшое количество места... но это привело меня к простому упрощению по-человечески возможно... так что я получил в основном это: p=123234,123235,123237,288721,... Все еще не долгосрочное решение (я думаю, мне все еще нужно какое-то сжатие/кодирование), но этого может быть достаточно пока эта система не будет полностью переписана в следующем году. - person jrista; 28.07.2009
comment
Как я уже сказал, гораздо лучшим решением будет сжатие и base64. Нам удалось сократить строку URL-адреса из 1700 символов до 1000 символов с помощью convert to json -> сжать -> base64. - person BYK; 28.07.2009
comment
Какую компрессию вы использовали? Я возился с алгоритмами Хаффмана, опубликованными другими, но для данных, которые у меня есть, они недостаточно эффективны, чтобы компенсировать расширение кодировки... - person jrista; 29.07.2009
comment
Нам нужна эта функциональность в JS, поэтому я использовал библиотеку U-LZSS, которую можно найти в Google Code. Мне пришлось адаптировать его декомпрессор к PHP, но это не имело большого значения. Я предлагаю использовать gzip, если он уже реализован в ASP.NET и вам не нужен JS. LZSS - это вариант LZW, и он может быть не таким эффективным, как алгоритмы на основе DEFLATE, но попробовать стоит;) - person BYK; 29.07.2009
comment
Проблема не в скорости, а в том, что созданный URL слишком длинный. Gzip, используемый в сети, не поможет мне со слишком длинным URL-адресом ... Я надеялся сделать что-то, что сократит длину URL-адреса перед отправкой запроса. - person jrista; 29.07.2009
comment
Вы меня неправильно поняли. Я имел в виду сжатие строки запроса, а не встроенный gzip браузеров. Думайте точно так же, как пример json, который я привел. Сожмите исходную строку запроса, закодируйте ее в base64, чтобы она не удваивалась или утраивалась, когда вы кодируете ее по URL-адресу, а затем присваивайте ее однобуквенной переменной. Теперь у вас есть гораздо более короткий URL-адрес и строка запроса, содержащая точно такие же данные. - person BYK; 29.07.2009

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

person user134706    schedule 28.07.2009

Ответ из учебника - использовать POST. Почему это невозможно? Причина, по которой был изобретен POST, заключалась в том, чтобы обойти ограничения длины в GET.

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

person Jay    schedule 28.07.2009
comment
Причина, по которой был изобретен POST, заключалась в том, чтобы не обойти ограничения длины в GET. - person Duncan Beevers; 28.07.2009
comment
Причина, по которой был изобретен POST, заключалась в том, чтобы обойти ограничения длины в GET. Извините, но я смеялся до упаду, когда читал это. - person Josh Stodola; 28.07.2009
comment
Хорошо, я готов получить образование. Зачем тогда придумали POST? Да, я понимаю, что технически GET должен использоваться для идемпотентных транзакций и POST для неидемпотентных транзакций. Но в реальной жизни практическая разница между ними заключается в том, что GET имеет резкое ограничение длины, а POST — нет. В JSP GET и POST обрабатываются по одной и той же логике. Вы должны сделать все возможное, чтобы проверить и отличить их. - person Jay; 30.07.2009

Ограничение строки запроса на клиенте или сервере?

Если проблема заключается только в том, что клиент не будет отправлять длинную строку GET, возможно, вы можете отправить запрос на прокси-сервер, который затем перенаправит запрос как GET.

person Duncan Beevers    schedule 28.07.2009
comment
для справки об ограничении строки запроса: en.wikipedia.org/wiki/Query_string#Compatibility_issues - person smoothdeveloper; 24.01.2010

Это для хранения информации о состоянии между страницами? Если это так, можно использовать файл cookie со значением GUID как таковым:

_SESSIONID=3F2504E0-4F89-11D3-9A0C-0305E82C3301

И сохраните информацию о сеансе на стороне сервера. Сеанс однозначно идентифицируется с помощью GUID, поэтому можно легко получить большой объем информации непосредственно на сервере.

Затем все, что вам нужно для отправки/получения на стороне клиента, — это идентификатор сеанса, а также сгенерированная клиентом информация (поля GET/POST).

person Andrew Moore    schedule 28.07.2009
comment
Это огромный набор идентификаторов, которые обрабатываются на стороне сервера. - person jrista; 28.07.2009
comment
Ну и один SESSIONID по клиенту подключился. Именно так PHP обрабатывает сеансы по умолчанию без потери реальной производительности. Ваше приложение на самом деле будет работать быстрее, так как меньше передачи. - person Andrew Moore; 28.07.2009