JavaScript로 URL을 인코딩 하시겠습니까?


2469

GET 문자열에 넣을 수 있도록 JavaScript를 사용하여 URL을 어떻게 안전하게 인코딩합니까?

var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;

myUrl두 번째 줄 에서 변수 를 인코딩해야한다고 가정 합니까?


22
encodeURI ()decodeURI ()을 살펴보십시오 .
Zack The Human


1
현재이 도구를 사용할 수 있습니다 phillihp.com/toolz/url-encode-decode을
phillihp

2
encodeURIComponent ()
Andrew

답변:


2791

내장 함수 encodeURIComponent (str)encodeURI (str)를 확인하십시오 .
귀하의 경우 다음과 같이 작동합니다.

var myOtherUrl = 
       "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

12
@cms가 설명을 추가하는 것은 어떻습니까? escape유효한 옵션이기도합니다.
hitautodestruct

11
@CMS에 따르면 encodeURIURL 인코딩에는 실제로 안전하지 않습니다.
Ifnot

13
이 같은 문자를 사용할 수 없습니다 전체 URL을 인코딩하기위한 것입니다 @AnaelFavre 때문에 :, /, @이 두 방법은 상호 교환 사용하지 않는 등, 당신은 당신이 올바른 방법을 사용하여 인코딩하는 것을 알고 있어야합니다.
Buu Nguyen


언급 한 바와 같이 이 페이지의 다른 답변에서 , 이 사이트는 잘이 방법을 사용하는 이유 사항
브래드 공원

1520

세 가지 옵션이 있습니다.

  • escape() 인코딩하지 않습니다 : @*/+

  • encodeURI() 인코딩하지 않습니다 : ~!@#$&*()=:/,;?+'

  • encodeURIComponent() 인코딩하지 않습니다 : ~!*()'

그러나 귀하의 경우에 URLGET 다른 페이지의 매개 변수, 당신은 사용해야 escape하거나 encodeURIComponent,하지만 encodeURI.

자세한 내용은 스택 오버플로 질문 모범 사례 : 이스케이프 또는 encodeURI / encodeURIComponent 를 참조하십시오 .


76
이스케이프와 함께 사용되는 문자 인코딩은 가변적입니다. UTF-8을 사용하는 encodeURI 및 encodeURIComponent를 사용하십시오.
erickson

6
조심해. 이 이스케이프는 ASCII가 아닌 문자를와 같이 유니 코드 이스케이프 시퀀스로 변환 %uxxx합니다.
opteronn

4
encodeURIComponent를 사용하고 있으며 파이프 문자를 인코딩하지 않습니다.
kevzettler

15
@kevzettler-왜 그렇게해야합니까? URI에서 파이프는 의미 상 중요하지 않습니다.
nickf

4
@GiovanniP : 독일어, 프랑스어, 일본어, 중국어, 아랍어 문자를 입력으로 허용하고 GET 또는 POST를 통해 이러한 매개 변수를 전달하는 사람들.
Tseng

180

와 붙어 있습니다 encodeURIComponent(). 이 함수 encodeURI()는 URL에서 의미가 중요한 많은 문자 (예 : "#", "?"및 "&")를 인코딩하지 않습니다.escape()는 더 이상 사용되지 않으며 "+"문자를 인코딩하지 않아도되며 서버에서 인코딩 된 공백으로 해석됩니다 (여기서 다른 사람들이 지적한 것처럼 비 ASCII 문자를 올바르게 URL 인코딩하지 않음).

다른 곳 의 차이점에encodeURI()encodeURIComponent() 대한 좋은 설명이 있습니다. URI의 구성 요소 (예 : 쿼리 문자열 매개 변수)로 안전하게 포함될 수 있도록 무언가를 인코딩하려면을 사용하려고합니다 encodeURIComponent().


83

가장 좋은 대답은에 사용 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}`;

22
첫 번째 물음표 (URL의 '쿼리'부분) 뒤에 % 20 만 + 기호로 바꿔야합니다. 찾아 보려고한다고 가정 해 보겠습니다 http://somedomain/this dir has spaces/info.php?a=this has also spaces. 로 변환해야 http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spaces하지만 많은 구현에서는 쿼리 문자열의 '% 20'을 '+'로 바꿀 수 있습니다. 그럼에도 불구하고 URL의 경로 섹션에서 '% 20'을 '+'로 바꿀 수 없으므로 +공백 이 아닌 디렉토리가 없으면 찾을 수 없음 오류가 발생 합니다.
Jochem Kuijpers

@Jochem Kuijpers는 디렉토리에 "+"를 넣지 않을 것입니다. 전체 URL 또는 전체 쿼리 문자열이 아닌 쿼리 매개 변수 값 자체 (또는 필요한 경우 키)에만 이것을 적용합니다.
라이언 테일러

인코딩 결과가 아닌 값을 바꾸려고합니다.
njzk2

1
@ njzk2는 불행히도 encodeURIComponent('+')당신에게 줄 것입니다 %2B. 따라서 두 개의 정규 표현식을 사용해야합니다 ... '+'는 ''가 결국 다르게 인코딩되기 때문에 이것이 작동하는 이유입니다.
Ryan Taylor

% 20을 "+"로 번역 할 이유가 없습니다. ASCII 공간에 대한 유효한 이스케이프 시퀀스는 % 20이며 "+"가 아니며 RFC 3986 ( tools.ietf.org/html/rfc3986 )에 언급되어 있지 않습니다 . "+"는 1990 년대에 사용되었습니다. 현재는 사용되지 않으며 레거시 이유로 만 지원됩니다. 사용하지 마십시오.
xhienne

40

jQuery를 사용하는 경우 $.param방법을 사용합니다. URL은 오브젝트 맵핑 필드를 값으로 인코딩하므로 각 값에서 이스케이프 메소드를 호출하는 것보다 읽기 쉽습니다.

$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1

제공된 예가 충분하다고 생각합니다. 당신은에 $ .PARAM에 대한 자세한 정보가 필요하면 api.jquery.com/jquery.param
Maksym Kozlenko을

거의 모든 사람들이 jQuery를 사용하고 있으며 encoreURIComponent 대신에 이것에 더 편안하다고 느낍니다
Cyril

12

encodeURIComponent ()가 갈 길입니다.

var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

그러나 PHP 버전 urlencode()과 는 약간의 차이가 있으며 @CMS에서 언급했듯이 모든 문자를 인코딩하지는 않습니다. http://phpjs.org/functions/urlencode/의 사람들 은 js를 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', '+');
}

10

앞에서 말한 것처럼 URL을 인코딩하려면 두 가지 기능이 있습니다.

encodeURI()

encodeURIComponent()

두 가지 모두 존재하는 이유는 첫 번째 URL은 너무 많은 것들을 이스케이프하지 않은 채 남겨 둘 위험이있는 URL을 유지하고 두 번째는 필요한 모든 것을 인코딩하기 때문입니다.

첫 번째로, 새로 이스케이프 된 URL을 주소 표시 줄 (예 :)에 복사하면 작동합니다. 그러나 이스케이프 처리되지 않은 '&'는 필드 구분 기호를 방해하고 '='는 필드 이름 및 값을 방해하며 '+'는 공백처럼 보입니다. 그러나 탈출하려는 URL의 특성을 유지하려는 간단한 데이터의 경우 작동합니다.

두 번째는 문자열의 어떤 것도 URL을 방해하지 않도록하기 위해 필요한 모든 것입니다. URL은 간섭없이 가능한 한 사람이 읽을 수 있도록 여러 중요하지 않은 문자를 이스케이프 처리하지 않습니다. 이 방법으로 인코딩 된 URL은 더 이상 이스케이프를 해제하지 않으면 URL로 작동하지 않습니다.

따라서 시간이 걸리는 경우 항상 encodeURIComponent ()를 사용하려고합니다. 이름 / 값 쌍을 추가하기 전에이 함수를 사용하여 이름과 값을 모두 쿼리 문자열에 추가하기 전에 인코딩하십시오.

encodeURI ()를 사용하는 이유를 생각해내는 데 어려움을 겪고 있습니다. 똑똑한 사람들에게 맡길 것입니다.


5

일반적인 자바 스크립트로 시도한 것과 비슷한 종류

function fixedEncodeURIComponent(str){
     return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}

5

우아한 방법

겸손한 의견으로 쿼리 매개 변수를 인코딩하는 가장 우아한 방법은 다음과 같은 매개 변수가있는 객체를 만드는 것입니다.

const queryParams = { param1: 'value1', param2: 'value2' }

다음을 사용하여 인코딩하십시오.

const queryString = new URLSearchParams(queryParams).toString()

이 답변에 언급 된 바와 같이 : https : //.com/a/53171438/7284582


4

이중 인코딩을 방지하려면 인코딩 전에 URL을 디코딩하는 것이 좋습니다 (예를 들어 이미 인코딩 된 사용자 입력 URL을 처리하는 경우).

우리가 abc%20xyz 123입력으로 가지고 있다고 가정 해 봅시다 (한 공간이 이미 인코딩되어 있습니다).

encodeURI("abc%20xyz 123")            //   wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"

4

URL 인코딩이란 무엇입니까?

URL 안에 특수 문자가있는 경우 URL을 인코딩해야합니다. 예를 들면 다음과 같습니다.

console.log(encodeURIComponent('?notEncoded=&+'));

이 예에서는 문자열을 제외한 모든 문자 notEncoded가 % 기호로 인코딩되어 있음을 알 수 있습니다. URL 인코딩은 백분율 인코딩 이라고도합니다. %로 모든 특수 문자를 이스케이프하므로 합니다. 그런 다음이 % 기호 뒤에 모든 특수 문자에는 고유 코드가 있습니다.

왜 URL 인코딩이 필요한가요?

특정 문자는 URL 문자열에서 특별한 값을 갖습니다. 예를 들어? 문자는 쿼리 문자열의 시작을 나타냅니다. 웹에서 리소스를 성공적으로 찾으려면 문자가 문자열의 일부 또는 URL 구조의 일부로 의미되는 시점을 구분해야합니다.

JS에서 URL 인코딩을 어떻게 달성 할 수 있습니까?

JS는 URL을 쉽게 인코딩하는 데 사용할 수있는 많은 유틸리티 기능을 제공합니다. 다음 두 가지 편리한 옵션이 있습니다.

  1. encodeURIComponent(): URI의 구성 요소를 인수로 사용하고 인코딩 된 URI 문자열을 반환합니다.
  2. 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이 더 이상 제대로 작동하지 않습니다.

따라서 (이름에서 알 수 있듯이) 다음을 사용하십시오.

  1. encodeURIComponent 인코딩하려는 URL의 특정 부분에
  2. encodeURI 인코딩하려는 전체 URL에서

3

아무것도 나를 위해 일하지 않았다. 내가보고있는 것은 로그인 페이지의 HTML로 코드 200으로 클라이언트 측으로 돌아 왔습니다. 로그인 페이지의 텍스트).

로그인 컨트롤러에서 다음 줄을 추가했습니다.

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;
            }
        }
    });
});

이제 문제가 없으며 매력처럼 작동합니다.


2

URL 문자열 인코딩

    var url = $ ( location ). attr ( 'href' ); // 현재 URL 가져 오기 // 또는 var url = 'folder / index.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

2

다음은 내장 된 함수 및 JS 의 라이브 데모 입니다 .encodeURIComponent()decodeURIComponent()

<!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>

1

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;
}

https://www.owasp.org/index.php/ESAPI_JavaScript_Readme


1

RFC 3986fixedEncodeURIComponent 을 엄격히 준수하는 기능 사용 :

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

1

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);
  });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.