GET 문자열에 넣을 수 있도록 JavaScript를 사용하여 URL을 어떻게 안전하게 인코딩합니까?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2"; var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
두 번째 줄 myUrl
변수를 인코딩해야 한다고 가정합니까?
질문자 :nickf
GET 문자열에 넣을 수 있도록 JavaScript를 사용하여 URL을 어떻게 안전하게 인코딩합니까?
var myUrl = "http://example.com/index.html?param=1&anotherParam=2"; var myOtherUrl = "http://example.com/index.html?url=" + myUrl;
두 번째 줄 myUrl
변수를 인코딩해야 한다고 가정합니까?
내장 함수인 encodeURIComponent(str) 및 encodeURI(str) 를 확인하십시오 .
귀하의 경우 다음과 같이 작동해야 합니다.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
세 가지 옵션이 있습니다.
escape()
는 인코딩하지 않습니다: @*/+
encodeURI()
는 인코딩하지 않습니다: ~!@#$&*()=:/,;?+'
encodeURIComponent()
는 인코딩하지 않습니다: ~!*()'
당신이 전달하려면 그러나 귀하의 경우, URL을 에 GET
다른 페이지의 매개 변수, 당신은 사용해야 escape
또는 encodeURIComponent
, 그러나 encodeURI
.
자세한 내용은 스택 오버플로 질문 모범 사례: 이스케이프 또는 encodeURI/encodeURIComponent 를 참조하세요.
encodeURIComponent()
. encodeURI()
함수는 URL에서 의미론적으로 중요한 많은 문자(예: "#", "?" 및 "&")를 인코딩하는 데 신경을 쓰지 않습니다. escape()
는 더 이상 사용되지 않으며 서버에서 인코딩된 공백으로 해석되는 "+" 문자를 인코딩하는 데 신경 쓰지 않습니다(여기에서 다른 사람들이 지적한 것처럼 비 ASCII 문자를 URL 인코딩하지 않음).
다른 곳에서는 encodeURI()
와 encodeURIComponent()
의 차이점에 대한 좋은 설명이 있습니다. URI의 구성 요소(예: 쿼리 문자열 매개변수)로 안전하게 포함될 수 있도록 무언가를 인코딩하려면 encodeURIComponent()
를 사용하고 싶습니다.
가장 좋은 대답은 쿼리 문자열의 값 encodeURIComponent
그러나 많은 API가 " "를 "+"로 바꾸고 싶어하므로 다음을 사용해야 했습니다.
const value = encodeURIComponent(value).replace('%20','+'); const url = 'http://example.com?lang=en&key=' + value
escape
는 다른 브라우저에서 다르게 구현되며 encodeURI
는 많은 문자(예: # 및 /)를 인코딩하지 않습니다. 전체 URI/URL에서 깨지지 않고 사용되도록 만들어졌습니다. 이는 매우 유용하거나 안전하지 않습니다.
그리고 @Jochem이 아래에서 지적했듯이 encodeURIComponent()
를 사용할 수 있지만 어떤 이유로든 이러한 API는 +
를 원하지 않는 것 같으므로 평범한 오래된 encodeURIComponent
가 잘 작동합니다.
예시:
const escapedValue = encodeURIComponent(value).replace('%20','+'); const escapedFolder = encodeURIComponent('My Folder'); // no replace const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
qs npm 패키지 를 사용하는 것이 좋습니다.
qs.stringify({a:"1=2", b:"Test 1"}); // gets a=1%3D2&b=Test+1
JS 객체와 함께 사용하는 것이 더 쉽고 모든 매개변수에 대해 적절한 URL 인코딩을 제공합니다.
jQuery를 사용하는 경우 $.param
메서드를 사용합니다. URL은 개체 매핑 필드를 값으로 인코딩하므로 각 값에 대해 이스케이프 메서드를 호출하는 것보다 읽기 쉽습니다.
$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
encodeURIComponent()가 갈 길입니다.
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
urlencode()
와 약간의 차이점이 있으며 @CMS가 언급했듯이 모든 문자를 인코딩하지는 않는다는 점을 명심해야 합니다. http://phpjs.org/functions/urlencode/의 사람들 phpencode()
와 동일하게 만들었습니다.
function urlencode(str) { str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. return encodeURIComponent(str) .replace('!', '%21') .replace('\'', '%27') .replace('(', '%28') .replace(')', '%29') .replace('*', '%2A') .replace('%20', '+'); }
이전에 말했듯이 URL을 인코딩하려면 두 가지 기능이 있습니다.
encodeURI()
그리고
encodeURIComponent()
둘 다 존재하는 이유는 첫 번째는 너무 많은 것을 이스케이프 처리하지 않은 채로 남겨둘 위험이 있는 URL을 유지하고 두 번째는 필요한 모든 것을 인코딩하기 때문입니다.
첫 번째로 새로 이스케이프된 URL을 주소 표시줄에 복사할 수 있으며(예:) 작동합니다. 그러나 이스케이프 처리되지 않은 '&'는 필드 구분 기호를 방해하고 '='는 필드 이름과 값을 방해하며 '+'는 공백처럼 보입니다. 그러나 이스케이프하는 항목의 URL 특성을 유지하려는 간단한 데이터의 경우 이 방법이 작동합니다.
두 번째는 문자열이 URL을 방해하지 않도록 하기 위해 필요한 모든 것입니다. URL이 간섭 없이 가능한 한 사람이 읽을 수 있도록 유지되도록 중요하지 않은 다양한 문자를 이스케이프 처리하지 않습니다. 이 방법으로 인코딩된 URL은 이스케이프를 해제하지 않으면 더 이상 URL로 작동하지 않습니다.
따라서 시간을 할애할 수 있다면 항상 encodeURIComponent()를 사용하는 것이 좋습니다. 이름/값 쌍을 추가하기 전에 쿼리 문자열에 추가하기 전에 이 함수를 사용하여 이름과 값을 모두 인코딩합니다.
나는 encodeURI()를 사용해야 하는 이유를 찾는 데 어려움을 겪고 있습니다. 나는 그것을 똑똑한 사람들에게 맡길 것입니다.
다른 답변이 작성된 이후로 URLSearchParams API가 도입되었습니다. 다음과 같이 사용할 수 있습니다.
const queryParams = { param1: 'value1', param2: 'value2' } const queryString = new URLSearchParams(queryParams).toString()
특정 예의 경우 다음과 같이 사용합니다.
const myUrl = "http://example.com/index.html?param=1&anotherParam=2"; const myOtherUrl = "http://example.com/index.html"; myOtherUrl.search = new URLSearchParams({url: myUrl}); console.log(myOtherUrl.toString());
일반 자바 스크립트로 시도한 비슷한 종류의 것
function fixedEncodeURIComponent(str){ return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A"); }
URL 내부에 특수 문자가 있는 경우 URL을 인코딩해야 합니다. 예를 들어:
console.log(encodeURIComponent('?notEncoded=&+'));
notEncoded
문자열을 제외한 모든 문자가 % 기호로 인코딩되어 있음을 관찰할 수 있습니다. URL 인코딩은 모든 특수 문자를 %로 이스케이프하므로 백분율 인코딩이라고도 합니다. 그런 다음이 % 기호 뒤에 모든 특수 문자에는 고유 코드가 있습니다.
특정 문자는 URL 문자열에 특수 값이 있습니다. 예를 들어, ? 문자는 쿼리 문자열의 시작을 나타냅니다. 웹에서 리소스를 성공적으로 찾으려면 문자가 문자열의 일부인지 URL 구조의 일부인지를 구별하는 것이 필요합니다.
JS는 URL을 쉽게 인코딩하는 데 사용할 수 있는 다양한 빌드 인 유틸리티 기능을 제공합니다. 다음은 두 가지 편리한 옵션입니다.
encodeURIComponent()
: URI의 구성 요소를 인수로 취하고 인코딩된 URI 문자열을 반환합니다.encodeURI()
: URI를 인수로 취하고 인코딩된 URI 문자열을 반환합니다. 전체 URL(예: https://)을 encodeURIComponent()
전달하지 않도록 주의하십시오. 이것은 실제로 작동하지 않는 URL로 변환할 수 있습니다. 예를 들어:
// for a whole URI don't use encodeURIComponent it will transform // the / characters and the URL won't fucntion properly console.log(encodeURIComponent("http://www.random.com/specials&char.html")); // instead use encodeURI for whole URL's console.log(encodeURI("http://www.random.com/specials&char.html"));
전체 URL을 encodeURIComponent
넣으면 슬래시(/)도 특수 문자로 변환되는 것을 볼 수 있습니다. 이로 인해 URL이 더 이상 제대로 작동하지 않습니다.
따라서 (이름에서 알 수 있듯이) 다음을 사용하십시오.
encodeURIComponent
encodeURI
이중 인코딩을 방지하려면 인코딩하기 전에 URL을 디코딩하는 것이 좋습니다(예를 들어 사용자가 입력한 URL을 처리하는 경우 이미 인코딩되었을 수 있음).
abc%20xyz 123
이 있다고 가정해 보겠습니다(하나의 공백이 이미 인코딩되어 있음).
encodeURI("abc%20xyz 123") // wrong: "abc%2520xyz%20123" encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"
encodeURIComponent()
직접 사용하면 안됩니다.
RFC3986: URI(Uniform Resource Identifier): 일반 구문 살펴보기
하위 요소 = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
예약 문자의 목적은 URI 내의 다른 데이터와 구별할 수 있는 구분 문자 집합을 제공하는 것입니다.
RFC3986의 URI 정의에서 이러한 예약된 문자는 encodeURIComponent()
의해 이스케이프되지 않습니다.
MDN 웹 문서: encodeURIComponent()
RFC 3986(!, ', (, ) 및 *를 예약함)을 더 엄격하게 준수하려면 이러한 문자에 공식화된 URI 구분 용도가 없더라도 다음을 안전하게 사용할 수 있습니다.
MDN 웹 문서 기능 사용...
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }
아무것도 나를 위해 일하지 않았다. 내가 본 것은 로그인 페이지의 HTML이었고 코드 200으로 클라이언트 측에 돌아오는 것이었습니다. (처음에는 302지만 동일한 Ajax 요청이 다른 Ajax 요청 내부에 로그인 페이지를 로드했습니다. 이 요청은 일반 로드가 아닌 리디렉션이어야 했습니다. 로그인 페이지의 텍스트).
로그인 컨트롤러에서 다음 줄을 추가했습니다.
Response.Headers["land"] = "login";
그리고 전역 Ajax 핸들러에서 다음과 같이 했습니다.
$(function () { var $document = $(document); $document.ajaxSuccess(function (e, response, request) { var land = response.getResponseHeader('land'); var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location); if(land) { if (land.toString() === 'login') { window.location = redrUrl; } } }); });
이제 문제가 없으며 매력처럼 작동합니다.
인코딩 URL 문자열
var url = $(위치).attr('href'); //현재 URL 가져오기 //또는 var url = '폴더/인덱스.html?param=#23dd&noob=yes'; //또는 하나 지정
var encodedUrl = encodeURIComponent(url); console.log(encodedUrl); //outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes for more info go http://www.sitepoint.com/jquery-decode-url-string
다음은 함수에 내장된 encodeURIComponent()
및 decodeURIComponent()
JS의 라이브 데모 입니다.
<!DOCTYPE html> <html> <head> <style> textarea{ width:30%; height:100px; } </style> <script> // encode string to base64 function encode() { var txt = document.getElementById("txt1").value; var result = btoa(txt); document.getElementById("txt2").value = result; } // decode base64 back to original string function decode() { var txt = document.getElementById("txt3").value; var result = atob(txt); document.getElementById("txt4").value = result; } </script> </head> <body> <div> <textarea id="txt1">Some text to decode </textarea> </div> <div> <input type="button" id="btnencode" value="Encode" onClick="encode()"/> </div> <div> <textarea id="txt2"> </textarea> </div> <br/> <div> <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ== </textarea> </div> <div> <input type="button" id="btndecode" value="Decode" onClick="decode()"/> </div> <div> <textarea id="txt4"> </textarea> </div> </body> </html>
오늘(2020.06.12) 브라우저 Chrome 83.0, Safari 13.1, Firefox 77.0의 MacOs HighSierra 10.13.6에서 선택한 솔루션에 대한 속도 테스트를 수행합니다. 이 결과는 대규모 URL 인코딩에 유용할 수 있습니다.
encodeURI
(B)가 가장 빠른 것 같지만 url-s에는 권장되지 않습니다.escape
(A)는 빠른 크로스 브라우저 솔루션입니다.솔루션 A B C D E F의 경우 두 가지 테스트를 수행합니다.
function A(url) { return escape(url); } function B(url) { return encodeURI(url); } function C(url) { return encodeURIComponent(url); } function D(url) { return new URLSearchParams({url}).toString(); } function E(url){ return encodeURIComponent(url).replace(/[!'()]/g, escape).replace(/\*/g, "%2A"); } function F(url) { return encodeURIComponent(url).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); } // ---------- // TEST // ---------- var myUrl = "http://example.com/index.html?param=1&anotherParam=2"; [A,B,C,D,E,F] .forEach(f=> console.log(`${f.name} ?url=${f(myUrl).replace(/^url=/,'')}`));
This snippet only presents code of choosen solutions
Chrome에 대한 예시 결과
esapi 라이브러리를 사용하고 아래 함수를 사용하여 URL을 인코딩할 수 있습니다. 이 기능은 나머지 텍스트 내용이 인코딩되는 동안 인코딩 시 '/'가 손실되지 않도록 합니다.
function encodeUrl(url) { String arr[] = url.split("/"); String encodedUrl = ""; for(int i = 0; i<arr.length; i++) { encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i])); if(i<arr.length-1) encodedUrl = encodedUrl + "/"; } return url; }
RFC 3986 을 엄격히 준수 fixedEncodeURIComponent
함수를 사용하십시오.
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }
var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl).replace(/%20/g,'+');
인코딩된 모든 ' '를 대체하려면 /g 플래그를 잊지 마세요.
2021년 지금은 정말 안전하다고 생각합니다. 항상 URL()
인터페이스를 사용하여 URL을 구성하는 것을 고려해야 합니다. 그것은 당신을 위해 대부분의 일을 할 것입니다. 코드에 와서
const baseURL = 'http://example.com/index.html'; const myUrl = new URL(baseURL); myUrl.searchParams.append('param', '1'); myUrl.searchParams.append('anotherParam', '2'); const myOtherUrl = new URL(baseURL); myOtherUrl.searchParams.append('url', myUrl.href); console.log(myUrl.href); // Outputs: http://example.com/index.html?param=1&anotherParam=2 console.log(myOtherUrl.href); // Outputs: http://example.com/index.html?url=http%3A%2F%2Fexample.com%2Findex.html%3Fparam%3D1%26anotherParam%3D2 const params = new URLSearchParams(myOtherUrl.search); console.log(params.get('url')); // Outputs: http://example.com/index.html?param=1&anotherParam=2
이와 같은 것은 실패하지 않을 것입니다.
나는 항상 이것을 URL에 대한 항목을 인코딩하는 데 사용합니다. 인코딩할 필요가 없더라도 모든 단일 문자를 인코딩하기 때문에 이것은 완전히 안전합니다.
function urlEncode(text) { let encoded = ''; for (let char of text) { encoded += '%' + char.charCodeAt(0).toString(16); } return encoded; }
출처 : http:www.stackoverflow.com/questions/332872/encode-url-in-javascript
Windows에 pip를 어떻게 설치합니까? (0) | 2021.11.10 |
---|---|
**(이중 별표/별표) 및 *(별표/별표)는 매개변수에 대해 무엇을 합니까? (0) | 2021.11.10 |
글머리 기호가 없는 순서 없는 목록이 필요합니다. (0) | 2021.11.10 |
인스턴스 상태 저장을 사용하여 활동 상태를 저장하려면 어떻게 해야 합니까? (0) | 2021.11.10 |
#include의 차이점은 무엇입니까?<filename> 및 #include "파일 이름"? (0) | 2021.11.10 |