عندما كنت من المفترض أن استخدام الهروب بدلا من encodeURI / encodeURIComponent?
-
09-06-2019 - |
سؤال
عند ترميز سلسلة استعلام ليتم إرسالها إلى ملقم ويب - عندما تستخدمها escape()
وعندما تستخدمها encodeURI()
أو encodeURIComponent()
:
استخدام الهروب:
escape("% +&=");
أو
استخدام encodeURI() / encodeURIComponent()
encodeURI("http://www.google.com?var1=value1&var2=value2");
encodeURIComponent("var1=value1&var2=value2");
المحلول
الهروب()
لا تستخدم ذلك!escape()
هو محدد في القسم B. 2.1.2 الهروب و إدخال نص المرفق باء يقول:
...كل من ميزات اللغة والسلوكيات المحددة في هذا المرفق لديك واحد أو أكثر غير مرغوب فيه الخصائص و في غياب إرث من شأنه أن يكون استخدام إزالتها من هذه المواصفات....
...المبرمجين يجب عدم استخدام أو نفترض وجود هذه السمات والسلوكيات عند كتابة جديدة ECMAScript رمز....
السلوك:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape
خاصة يتم ترميز الأحرف باستثناء:@*_+-./
الست عشري شكل الشخصيات التي رمز وحدة قيمة 0xFF أو أقل ، رقمين تسلسل الهروب: %xx
.
بالنسبة الشخصيات مع أكبر رمز وحدة من أربعة أرقام شكل %uxxxx
يتم استخدامه.هذا غير مسموح به ضمن سلسلة الاستعلام (على النحو المحدد في RFC3986):
query = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
علامة النسبة المئوية مسموح فقط إذا كان مباشرة تليها اثنين hexdigits, في المئة تليها u
لا يسمح.
encodeURI()
استخدام encodeURI عندما كنت ترغب في العمل URL.جعل هذه الدعوة:
encodeURI("http://www.example.org/a file with spaces.html")
للحصول على:
http://www.example.org/a%20file%20with%20spaces.html
لا تتصل encodeURIComponent لأن ذلك من شأنه أن يدمر URL والعودة
http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html
encodeURIComponent()
استخدام encodeURIComponent عندما تريد ترميز قيمة معلمة URL.
var p1 = encodeURIComponent("http://example.org/?a=12&b=55")
ثم يمكنك إنشاء عنوان URL تحتاج:
var url = "http://example.net/?param1=" + p1 + "¶m2=99";
وسوف تحصل على هذا URL الكامل:
http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55¶m2=99
علما بأن encodeURIComponent لا الهروب '
حرف.مشترك هو علة استخدامه لإنشاء html سمات مثل href='MyUrl'
, التي يمكن أن تعاني حقنة علة.إذا كنت بناء html من السلاسل ، إما استخدام "
بدلا من '
للسمة يقتبس, أو إضافة طبقة إضافية من التشفير ('
يمكن ترميز %27).
لمزيد من المعلومات حول هذا النوع من الترميز يمكنك التحقق من: http://en.wikipedia.org/wiki/Percent-encoding
نصائح أخرى
الفرق بين encodeURI()
و encodeURIComponent()
هي بالضبط 11 الأحرف المشفرة بواسطة encodeURIComponent ولكن ليس قبل encodeURI:
أنا ولدت هذا الجدول بسهولة مع وحدة التحكم.الجدول في جوجل كروم مع هذا الرمز:
var arr = [];
for(var i=0;i<256;i++) {
var char=String.fromCharCode(i);
if(encodeURI(char)!==encodeURIComponent(char)) {
arr.push({
character:char,
encodeURI:encodeURI(char),
encodeURIComponent:encodeURIComponent(char)
});
}
}
console.table(arr);
لقد وجدت هذه المادة مفيدة :جافا سكريبت الجنون:سلسلة الاستعلام تحليل
لقد وجدت أنه عندما كنت أحاول أن أفهم لماذا decodeURIComponent لم يفك '+' بشكل صحيح.هنا مقتطف:
String: "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") = "A%20+%20B" Wrong!
encodeURI("A + B") = "A%20+%20B" Wrong!
encodeURIComponent("A + B") = "A%20%2B%20B" Acceptable, but strange
Encoded String: "A+%2B+B"
Expected Decoding: "A + B"
unescape("A+%2B+B") = "A+++B" Wrong!
decodeURI("A+%2B+B") = "A+++B" Wrong!
decodeURIComponent("A+%2B+B") = "A+++B" Wrong!
encodeURIComponent لا ترميز -_.!~*'()
, تسبب مشكلة في نشر البيانات php في سلسلة xml.
على سبيل المثال:
<xml><text x="100" y="150" value="It's a value with single quote" />
</xml>
العامة الهروب مع encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E
يمكنك أن ترى, اقتباس مفردة غير المشفرة.لحل المشكلة أنا خلقت وظائف اثنين لحل المسألة في مشروع ترميز URL:
function encodeData(s:String):String{
return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}
من أجل فك URL:
function decodeData(s:String):String{
try{
return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
}catch (e:Error) {
}
return "";
}
encodeURI() - الهروب() وظيفة جافا سكريبت الهروب ، وليس HTTP.
صغيرة جدول مقارنة جافا مقابلجافا سكريبت مقابلPHP.
1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode
char JAVA JavaScript --PHP---
[ ] + %20 %20 + %20
[!] %21 ! %21 %21 %21
[*] * * * %2A %2A
['] %27 ' %27 %27 %27
[(] %28 ( %28 %28 %28
[)] %29 ) %29 %29 %29
[;] %3B %3B %3B %3B %3B
[:] %3A %3A %3A %3A %3A
[@] %40 %40 @ %40 %40
[&] %26 %26 %26 %26 %26
[=] %3D %3D %3D %3D %3D
[+] %2B %2B + %2B %2B
[$] %24 %24 %24 %24 %24
[,] %2C %2C %2C %2C %2C
[/] %2F %2F / %2F %2F
[?] %3F %3F %3F %3F %3F
[#] %23 %23 %23 %23 %23
[[] %5B %5B %5B %5B %5B
[]] %5D %5D %5D %5D %5D
----------------------------------------
[~] %7E ~ %7E %7E ~
[-] - - - - -
[_] _ _ _ _ _
[%] %25 %25 %25 %25 %25
[\] %5C %5C %5C %5C %5C
----------------------------------------
char -JAVA- --JavaScript-- -----PHP------
[ä] %C3%A4 %C3%A4 %E4 %C3%A4 %C3%A4
[ф] %D1%84 %D1%84 %u0444 %D1%84 %D1%84
أنصح بعدم استخدام واحدة من تلك الطرق كما هو.الكتابة الخاصة بك وظيفة الذي يفعل الشيء الصحيح.
MDN وقد أعطى مثالا جيدا على ترميز url هو مبين أدناه.
var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);
console.log(header);
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"
function encodeRFC5987ValueChars (str) {
return encodeURIComponent(str).
// Note that although RFC3986 reserves "!", RFC5987 does not,
// so we do not need to escape it
replace(/['()]/g, escape). // i.e., %27 %28 %29
replace(/\*/g, '%2A').
// The following are not required for percent-encoding per RFC5987,
// so we can allow for a little better readability over the wire: |`^
replace(/%(?:7C|60|5E)/g, unescape);
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
تذكر أيضا أنهم جميعا ترميز مجموعات مختلفة من الشخصيات ، واختيار واحد التي تحتاج إليها بشكل مناسب.encodeURI() ترميز أحرف أقل من encodeURIComponent () ، الذي يشفر أقل (و أيضا مختلفة ، dannyp نقطة) حرفا من الهروب().
لغرض ترميز جافا سكريبت أعطت ثلاثة يحمل في ثناياه عوامل وظائف -
الهروب() - لا ترميز
@*/+
هذا الأسلوب هو مستنكر بعد ECMA 3 لذلك يجب تجنبها.encodeURI() - لا ترميز
~!@#$&*()=:/,;?+'
فإنه يفترض أن URI هو استكمال URI ، لذلك لا ترميز محفوظة الشخصيات التي لها معنى خاص في URI.وتستخدم هذه الطريقة عندما يكون القصد من ذلك هو تحويل URL الكامل بدلا من جزء من URL.على سبيل المثال -encodeURI('http://stackoverflow.com');
سوف تعطي - http://stackoverflow.comencodeURIComponent() -لا ترميز
- _ . ! ~ * ' ( )
هذه الوظيفة يشفر معرف الموارد الموحد (URI) مكون عن طريق استبدال كل مثيل من بعض الشخصيات من جانب واحد, اثنان, ثلاثة, أو أربعة تسلسلات الهروب تمثل UTF-8 ترميز الحرف.هذه الطريقة يجب أن تستخدم لتحويل مكون من URL.فعلى سبيل المثال بعض مدخلات المستخدم يحتاج إلى إلحاق على سبيل المثال -encodeURI('http://stackoverflow.com');
سوف تعطي - http%3A%2F%2Fstackoverflow.com
كل هذا الترميز تتم في UTF 8 أنا.e الشخصيات سيتم تحويلها في UTF-8 الشكل.
encodeURIComponent تختلف من encodeURI في ذلك ترميز محفوظة الشخصيات وعدد علامة # من encodeURI
لقد وجدت أن تجريب أساليب مختلفة هو جيد التعقل تحقق حتى بعد أن مؤشر جيد على الاستخدامات المختلفة والقدرات.
لتحقيق هذه الغاية وجدت هذا الموقع مفيدة للغاية في تأكيد شكوكي أن أفعل شيء مناسب.وقد ثبت أيضا مفيدة فك أحد encodeURIComponent رائد سلسلة التي يمكن أن تكون صعبة بل إلى تفسير.كبير المرجعية إلى:
مستوحاة من يوهان الجدول, لقد قرر تمديد الجدول.أردت أن أرى أي أحرف ASCII الحصول على ترميز.
var ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
var encoded = [];
ascii.split("").forEach(function (char) {
var obj = { char };
if (char != encodeURI(char))
obj.encodeURI = encodeURI(char);
if (char != encodeURIComponent(char))
obj.encodeURIComponent = encodeURIComponent(char);
if (obj.encodeURI || obj.encodeURIComponent)
encoded.push(obj);
});
console.table(encoded);
ويبين الجدول فقط ترميز الأحرف.خلايا فارغة يعني أن أصلي و ترميز الأحرف هي نفسها.
فقط أن تكون إضافية, انا إضافة آخر الجدول urlencode()
مقابل rawurlencode()
.الفرق الوحيد يبدو أن ترميز حرف مسافة.
<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
$obj = ["char" => $char];
if ($char != urlencode($char))
$obj["urlencode"] = urlencode($char);
if ($char != rawurlencode($char))
$obj["rawurlencode"] = rawurlencode($char);
if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
$encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>
لدي وظيفة...
var escapeURIparam = function(url) {
if (encodeURIComponent) url = encodeURIComponent(url);
else if (encodeURI) url = encodeURI(url);
else url = escape(url);
url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
return url;
};
الجواب المقبول هو جيد.تمديد على الجزء الأخير:
علما بأن encodeURIComponent لا الهروب ' حرف.مشترك الخلل هو استخدامه لإنشاء html سمات مثل href='MyUrl' ، يمكن أن تعاني حقنة علة.إذا كنت بناء html من سلاسل إما استخدام "بدلا من' السمة يقتبس, أو إضافة طبقة إضافية من التشفير (' يمكن ترميز %27).
إذا كنت تريد أن تكون على الجانب الآمن ، في المئة ترميز تحفظ الشخصيات يجب أن يكون ترميز كذلك.
يمكنك استخدام هذا الأسلوب إلى الهروب منها (المصدر موزيلا)
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
// fixedEncodeURIComponent("'") --> "%27"
الحديث كتابة @يوهان-echavarria الجواب:
console.log(
Array(256)
.fill()
.map((ignore, i) => String.fromCharCode(i))
.filter(
(char) =>
encodeURI(char) !== encodeURIComponent(char)
? {
character: char,
encodeURI: encodeURI(char),
encodeURIComponent: encodeURIComponent(char)
}
: false
)
)
أو إذا كان يمكنك استخدام جدول استبدال console.log
مع console.table
(على أجمل الإخراج).