Походит на очень простой вопрос здесь:
У меня есть программа, где кто-то вводит строку M&S
в форме и выполнении запроса. Я понимаю &
зарезервированный символ и поэтому должен быть закодирован. Проблема, это, кажется, требует кодирования дважды в некоторых контекстах.
Если URL используется в JavaScript onClick
событие, нормальное кодирование URL, кажется, хорошо работает (здесь, оператор может нажать на заголовок столбца к виду):
<td onClick="AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=161')">
Однако, если URL используется в привязке (хотя привязка на самом деле использует Ajax), этому, кажется, нужно кодирование дважды:
<a href="javascript:AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')" title='Refresh'>Refresh</a>
Оба из примеров выше хорошо работают. Однако они - сгенерированные рукой тестовые сценарии. К сожалению, в приложении, когда я на самом деле генерирую URL, я не знаю, как это будет используемым.
Если я кодирую параметр URL однажды (M%26S
), это хорошо работает в onClick
. Но используемый этот путь в привязке, сервер видит URL как ...Qry147=M&S&sortmethod1=147...
- таким образом, это, должно быть, было не закодировано прежде чем быть отданным к серверу.
Если я кодирую его дважды (M%2526S
), работы привязки, но для onClick
, сервер видит ...Qry147=M%2526S...
.
Я получаю чувство, что я пропускаю что-то здесь. Существует ли способ сделать эту работу тем же в обоих случаях?
Если вы построите весь текст HTML с помощью простых шагов, некоторые трудности исчезнут. Итак, если взять ваш пример, вы хотите закодировать следующий параметр запроса:
M&S
Когда вы вставляете эту строку в качестве параметра запроса в URL, вы должны закодировать ее, как вы уже знаете. Закодированная строка имеет вид M%26S
. Полный URL выглядит так:
http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=147
Теперь этот URL встроен в код JavaScript, и в этом случае нужны только одинарные кавычки с обоих концов:
'http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=147'
Весь код JavaScript выглядит так:
AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')
Теперь весь этот текст используется в контексте HTML, который интерпретируется как URL, поэтому его снова нужно закодировать:
AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')
И, наконец, поскольку вы вставляете этот текст в HTML, вам нужно преобразовать его в htmlescape:
AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')
Вот почему вы заканчиваете:
<a href="javascript:AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')" title='Refresh'>Refresh</a>
Обычно я избегаю этих проблем с кодировкой, не помещая строку M&S
непосредственно в событие onclick или якорь. В общем, нельзя кодировать событие onclick и якорь одинаково, поскольку процесс декодирования для них различен:
onclick: html -> js -> url
anchor: html -> url -> js -> url
Но подождите... если написать вспомогательную функцию вроде этой, она работает:
function myQuery(q) {
var encodedQ = encodeURIComponent(q); // TODO: which character encoding is used here?
var url = 'http://10.0.0.195/program.exe?Qry147=' + encodedQ + '&sortmethod1=147';
var response = AJAX_Get(url);
// TODO: handle errors
}
Теперь вы можете написать:
<a href="javascript:myQuery('M&S')">anchor</a>
<a onclick="myQuery('M&S')">event</a>
Этот трюк работает, потому что в случае якоря больше нет %
.
Мне дали кое-что взломать решение из другого источника, но оно работает довольно хорошо.
Просто заменив:
с:
Действие onClick одинаково работает с привязками и другими элементами. Очевидно, любые части приложения, которые написали свои собственные фрагменты HTML, могут по-прежнему иметь проблему, но это незначительное изменение, чтобы сделать этот обходной путь в основном коде, поэтому я сейчас использую этот путь.
РЕДАКТИРОВАТЬ: просто заметил здесь свой ответ и понял, что это решение вызвало больше проблем, чем решило. В конце концов я нашел время, чтобы изменить его, чтобы он работал должным образом (чтобы он использовал правильный метод экранирования в нужное время.
Я рекомендую сохранять параметр в незакодированной форме и затем кодировать во время его использования, будь то событие onClick или привязка.