Javascript читает "%%" как "%" и "%%"?
При написании теста я сравнивал строки. И тест вернулся, как неудача. Я вручную скопировал вставку строки, и она работает...
Обратите внимание на синтаксис строки mysql; но он никогда не касается mysql до этого момента.
Console.logged copy + paste Обе строки выглядят следующим образом:
console.log(replaced);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"
console.log(sqlQuery0);
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE '%' AND influencer_name = ?"
Это не должно терпеть неудачу, но это так. Поэтому я хотел посмотреть, где это не удается:
it( "submits the proper first sql query", function(){
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
if (replaced[i] != sqlQuery0[i] ){
console.log(replaced.slice(i-10,i+10));
console.log(sqlQuery0.slice(i-10,i+10);
break
}
}
})
В МОЙ СУПРУГ ВЫШЕ ВЕРНУТЬСЯ ВЕРНУТЬСЯ...
me LIKE '%' AND inf
me LIKE '%' AND infl
Они не могут быть разной длины.... правильно. Я снова попытался.
it( "submits the proper first sql query", function(){
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
})
И к моему большому удивлению:
|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
Но первая строка имеет длину 19!
Мой последний аттапт:
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
for (var i = 0; i < replaced.length; i++) {
console.log(replaced[i], sqlQuery0[i]);
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ replaced.slice(i-10,i+10)+'|',replaced.slice(i-10,i+10).length);
console.log('|'+sqlQuery0.slice(i-10,i+10)+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
дал мне это:
n n
a a
m m
e e
L L
I I
K K
E E
' '
% %
% '
|me LIKE '%' AND inf| 20
|me LIKE '%' AND infl| 20
По-видимому, "%%" интерпретируется как% и %%, как это может быть?
больше:
var replaced = dao.SQLquery[0].replace(/ +/g, ' ');
console.log(sqlQuery0)
for (var i = 0; i < replaced.length; i++) {
console.log(replaced[i], sqlQuery0[i]);
if (replaced[i] != sqlQuery0[i] ){
console.log('|'+ JSON.stringify(replaced.slice(i-10,i+10))+'|',replaced.slice(i-10,i+10).length);
console.log('|'+ JSON.stringify(sqlQuery0.slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
console.log('|'+ JSON.stringify(dao.SQLquery[0].slice(i-10,i+10))+'|',sqlQuery0.slice(i-10,i+10).length);
break
}
}
|"me LIKE '%' AND inf"| 20
|"me LIKE '%' AND infl"| 20
|"ame LIKE '%' AND in"| 20
Ответы
Ответ 1
Как отмечали другие, у вас, вероятно, есть какой-то скрытый символ Unicode в одной из строк. Лучший способ увидеть - использовать charCodeAt()
, чтобы увидеть, какие кодовые точки на самом деле там.
Например:
var a = 'foo\u200bbar';
var b = 'foobar';
console.log('a = "' + a + '"');
console.log('b = "' + b + '"');
function toCodePointArray(str) {
var result = [];
for (var i = 0; i < str.length; i++) {
result.push(str.charCodeAt(i));
}
return result;
}
console.log('toCodePointArray(a) = ', toCodePointArray(a));
console.log('toCodePointArray(b) = ', toCodePointArray(b));
Когда я запускаю это, я получаю:
a = "foobar"
b = "foobar"
toCodePointArray(a) = [ 102, 111, 111, 8203, 98, 97, 114 ]
toCodePointArray(b) = [ 102, 111, 111, 98, 97, 114 ]
Здесь скрытый символ четко отображается как 8203, который является десятичным эквивалентом 0x200b, который является пространством нулевой ширины Unicode.
Ответ 2
расширяя то, что сказал @Matt Ball и @blm, у вас, скорее всего, есть "невидимый" символ в тексте, который находится в вашей "замененной" переменной. Чтобы проверить это, используйте шестнадцатеричный редактор и вставьте текст из переменных "replace" и sqlQuery0: вы должны видеть, что вокруг символа "%" у вас есть невидимый символ типа "00" NUL или "1E", разделитель записей.
Вы можете использовать этот онлайн-инструмент Hex Viewer для тестирования https://hexed.it/?hl=en
чтобы увидеть коды ASCII, на которые я ссылаюсь, проверьте таблицу ascii http://www.asciitable.com/
Ответ 3
чтобы избежать этой проблемы, которая создает дополнительные биты, используйте hex char val. для% it 0x25
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE "X'250225'" AND influencer_name = ?"
или даже
"SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE "%X'250225'%" AND influencer_name = ?"
Второй способ заключается в использовании Locate для более простых шестнадцатеричных привязок, но это немного медленнее.
"SELECT COUNT(*) FROM interaction WHERE LOCATE(X'25', ambassador_name) > 0 AND influencer_name = ?"
также, как говорит Роб Уилсон, чтобы избежать лишних беспорядочных битов в юникодах при использовании LIKE, всегда связывайте PDO:: PARAM_STR для LIKE. В процессе ускорения инъекции PDO также очищает эти дополнительные биты.
SELECT COUNT(*) FROM interaction WHERE ambassador_name LIKE ? AND influencer_name = ?
bindParam(1, "X'250225'", PDO::PARAM_STR);
или даже
bindParam(1, "%X'250225'%", PDO::PARAM_STR);