JavaScriptでURLをエンコードしますか?


2470

GET文字列に入れることができるように、JavaScriptを使用してURLを安全にエンコードするにはどうすればよいですか?

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

myUrlその2行目の変数をエンコードする必要があると思いますか?


22
encodeURI()decodeURI()を調べてみてください。
ザックザヒューマン

JavaScript urlencode関数を参照してください。
Yanni

1
このツールは、ここで使用できます。phillihp.com
toolz

2
encodeURIComponent()
Andrew

回答:


2791

組み込み関数encodeURIComponent(str)encodeURI(str)をチェックしてください。
あなたの場合、これはうまくいくはずです:

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

12
@cmsの説明を追加してみませんか?escapeも有効なオプションです。
hitautodestruct 2012年

11
@CMSによるとencodeURI、URLエンコーディングは本当に安全ではありません。
2013年

13
のような文字を許可していない全体のURLをエンコードするためのものです@AnaelFavreので:/@これらの2つの方法は、交換可能に使用されるようにされていないなど、あなたは右のメソッドを使用するようにエンコードされているかを知る必要があります。
ブウグエン


このページの別の回答で述べたようこのサイトでは、この方法を使用する理由を詳しく説明しています
Brad Parks

1522

次の3つのオプションがあります。

  • escape() エンコードしません: @*/+

  • encodeURI() エンコードしません: ~!@#$&*()=:/,;?+'

  • encodeURIComponent() エンコードしません: ~!*()'

しかし、あなたの場合、URLGET他のページのパラメーターに渡したい場合は、escapeまたはを使用する必要encodeURIComponentがありencodeURIますが、は使用しないでください。

詳細については、スタックオーバーフローの質問のベストプラクティス:エスケープ、またはencodeURI / encodeURIComponentを参照してください。


76
エスケープで使用される文字エンコーディングは可変です。UTF-8を使用するencodeURIおよびencodeURIComponentを使用します。
エリクソン2008

6
注意してください。そのエスケープは、非ASCII文字をなどのUnicodeエスケープシーケンスに変換し%uxxxます。
opteronn 2010年

4
encodeURIComponentを使用していますが、パイプ文字をエンコードしないことに気づきました|
kevzettler 2011年

15
@kevzettler-なぜそれをする必要があるのですか?パイプは、URIでは意味的に重要ではありません。
nickf 2011年

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
%20は、最初の疑問符(URLの「クエリ」部分)の後の+記号のみで置き換えてください。にアクセスしたいとし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ので、2つの正規表現を使用する必要があります...これはちょっとうまくいく理由だと思います。
Ryan Taylor

%20を「+」に変換する理由はありません。ASCIIスペースの有効なエスケープシーケンスは、RFC 3986(tools.ietf.org/html/rfc3986)で言及されていない「+」ではなく、%20 です。「+」は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 Duchon-Doris

12

encodeURIComponent()を使用する方法です。

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

urlencode()ただし、phpのバージョンとの小さな違いがあり、@ 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をエンコードするには、2つの関数があります。

encodeURI()

そして

encodeURIComponent()

両方が存在する理由は、1つ目はURLを保持し、エスケープしないものを多く残してしまうリスクがある一方で、2つ目は必要なすべてをエンコードするためです。

最初の方法では、新しくエスケープされたURLを(たとえば)アドレスバーにコピーできます。ただし、エスケープされていない '&'はフィールド区切り文字を妨害し、 '='はフィールド名と値を妨害し、 '+'はスペースのように見えます。しかし、エスケープするもののURLの性質を保持したいときに単純なデータの場合、これは機能します。

2つ目は、文字列内の何もURLに干渉しないようにするために必要なすべてのことです。さまざまな重要でない文字をエスケープせずに残すため、URLは干渉を受けずに可能な限り人間が読める形式のままです。この方法でエンコードされたURLは、エスケープ解除しないとURLとして機能しなくなります。

したがって、時間がかかる場合は、常にencodeURIComponent()を使用する必要があります。名前と値のペアを追加する前に、この関数を使用して名前と値の両方をエンコードしてから、クエリ文字列に追加します。

encodeURI()を使用する理由を考え出すのに苦労しています-それは賢い人に任せます。


5

私が通常のjavascriptで試したのと同じようなもの

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 : //stackoverflow.com/a/53171438/7284582


4

二重エンコードを防ぐには、エンコードする前にURLをデコードすることをお勧めします(たとえば、ユーザーが入力したURLを扱っている場合は、すでにエンコードされている可能性があります)。

abc%20xyz 123入力があるとしましょう(1つのスペースはすでにエンコードされています)。

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文字列で特別な値を持っています。たとえば、?文字はクエリ文字列の始まりを示します。Web上のリソースを正常に見つけるために、文字が文字列の一部またはURL構造の一部として意図されている場合を区別する必要があります。

JSでURLエンコーディングを実現するにはどうすればよいですか。

JSは、URLを簡単にエンコードするために使用できる多数の組み込みユーティリティ関数を提供しています。これらは2つの便利なオプションです。

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

encodeURIComponentスラッシュ(/)も特殊文字に変換されるので、URL全体を配置したことがわかります。これにより、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 = $ 場所)。attr 'href' ); //現在のURLを取得// OR var url = 'folder / index.html?param =#23dd&noob = yes' ; //または1つ指定 
    
      

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

ここでLIVE DEMOencodeURIComponent()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>

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

fixedEncodeURIComponent関数を使用してRFC 3986に厳密に準拠します

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

1

encodeURIComponent()直接使用しないでください。

RFC3986:Uniform Resource Identifier(URI):Generic Syntaxをご覧ください。

sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "、" / ";" / "="

予約文字の目的は、URI内の他のデータと区別できる区切り文字のセットを提供することです。

RFC3986のURI定義からのこれらの予約文字は、によってエスケープされませんencodeURIComponent()

MDN Webドキュメント:encodeURIComponent()

RFC 3986(!、 '、(、)、および*を予約する)を厳守するために、これらの文字に正式なURI区切りの使用法がない場合でも、以下を安全に使用できます。

MDN Webドキュメント機能を使用する...

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.