如何在我的javascript

时间:2017-10-27 15:31:30

标签: javascript jquery url urlencode url-encoding

我有以下JavaScript根据用户输入构建url参数: -

$(document).ready(function(){

    $('#button').click(function(e) {  
        var count=1;
        var s="";

        var inputvalue = $("#journal").val();
        var inputvalue2 = $("#keywords").val();
        var inputvalue3 = $("#datepub").val();
        var inputvalue4 = $("#title").val();
        var inputvalue5 = $("#localcurrency").val();
        var inputvalue6 = $("#locations").val();
        var inputvalue7 = $("#dropdown1").val();
        var inputvalue8 = $("#dropdown2").val();

        if(inputvalue!=null && inputvalue!="")
        {
        s = s+ "FilterField"+count+"=Journal&FilterValue"+count+"="+inputvalue+"&";
        count++;
        }
        if(inputvalue2!=null && inputvalue2!="")
        {
        s = s+ "FilterField"+count+"=KeyWords&FilterValue"+count+"="+inputvalue2+"&";
        count++;
        }
        if(inputvalue3!=null && inputvalue3!="")
        {
        s = s+ "FilterField"+count+"=datepub&FilterValue"+count+"="+inputvalue3+"&";
        count++;
        }
        if(inputvalue4!=null && inputvalue4!="")
        {
        s = s+ "FilterField"+count+"=Title&FilterValue"+count+"="+inputvalue4+"&";
        count++;
        }
        if(inputvalue5!=null && inputvalue5!="")
        {
        s = s+ "FilterField"+count+"=localcurrency&FilterValue"+count+"="+inputvalue5+"&";
        count++;
        }
        if(inputvalue6!=null && inputvalue6!="")
        {
        s = s+ "FilterField"+count+"=locations&FilterValue"+count+"="+inputvalue6+"&";
        count++;
        }
        if(inputvalue7!=null && inputvalue7!="")
        {
        s = s+ "FilterField"+count+"=dropdown1&FilterValue"+count+"="+inputvalue7+"&";
        count++;
        }
        if(inputvalue8!=null && inputvalue8!="")
        {
        s = s+ "FilterField"+count+"=dropdown2&FilterValue"+count+"="+inputvalue8+"&";
        count++;
        }

        window.location.replace("/teamsites/Bib%20Test/Forms/search.aspx?"+s);

    });
});
</script> 

现在上面的脚本将生成诸如

之类的URL
http://***/teamsites/Bib%20Test/Forms/search.aspx?FilterField1=Journal&FilterValue1=123

http://***/teamsites/Bib%20Test/Forms/search.aspx?FilterField1=Journal&FilterValue1=123&FilterField2=localcurrency&FilterValue2=USD&

并且事情进展顺利,直到我尝试传递包含&的搜索参数。例如,我想搜索其日志= General&Procedure的记录,因此使用上面的代码,URL将如下所示: -

http://***/teamsites/Bib%20Test/Forms/search.aspx?FilterField1=Journal&FilterValue1=General&Procedure&

并且我没有得到任何结果,因为应用程序假设Procudure是参数而不是FilterValue1的一部分..现在要解决这个特定问题,我定义构建具有encodeURIComponent()功能的网址参数如下: -

var inputvalue = encodeURIComponent($("#journal").val());
var inputvalue2 = encodeURIComponent($("#keywords").val());
var inputvalue3 = encodeURIComponent($("#datepub").val());
var inputvalue4 = encodeURIComponent($("#title").val());
var inputvalue5 = encodeURIComponent($("#localcurrency").val());
var inputvalue6 = encodeURIComponent($("#locations").val());
var inputvalue7 = encodeURIComponent($("#dropdown1").val());
var inputvalue8 = encodeURIComponent($("#dropdown2").val());

现在生成的网址如下: -

http://***teamsites/Bib%20Test/Forms/search.aspx?FilterField1=Journal&FilterValue1=General%26Procedure

我得到了预期的结果.. 但不确定使用encodeURIComponent()仅对参数值进行编码是一个有效的修复,如果它是查询字符串参数的一部分,我将编码&,但仍然包含网址非编码&分隔url参数..现在我从最后一个url获得的结果是正确的..但不确定我是否正确地做事情?是否有内置功能为我做这项工作? 感谢

5 个答案:

答案 0 :(得分:2)

以下是网址语法的来源:

您会注意到查询组件的确切内容未标准化。它的simple definition是:

  

查询组件由第一个问题指示      标记(“?”)字符并以数字符号(“#”)字符结束      或者在URI的末尾。

但是,事实上的标准是使用&符号(&)作为分隔符。使用此约定,只要此字符也出现在您的数据中并且不是分隔符,您必须“百分比编码”它,as per the standard

  

百分比编码机制用于表示组件中的数据八位字节,当该八位位组的相应字符位于允许的集合之外或被用作该组件的分隔符或在其内部时      成分

您很容易理解其他特殊字符,例如=%#,如果它们出现在您的数据中,也必须进行百分比编码。编码甚至更特殊的字符也没有坏处。

因此,如果您遵循此约定,则查询组件的格式应为:

?field1=value1&field2=value2

每个fieldvalue都是百分比编码的。在JavaScript中,您确实可以方便地使用encodeURIComponent函数。不要忘记对字段进行编码!

此外,由于您的用例非常常见,因此有足够的库可以为您处理此类转换,例如: URI.js

但是既然你提到使用jQuery,你可以方便地使用jQuery.param进行转换:

  

创建适合在URL查询字符串或Ajax请求中使用的数组,普通对象或jQuery对象的序列化表示形式。如果传递了jQuery对象,它应该包含具有名称/值属性的输入元素。

$(document).ready(function() {
  $('#button').click(retrieveInputsValues);

  retrieveInputsValues();
});

function retrieveInputsValues() {
  var inputIds = [
    'Journal',
    'KeyWords',
    'datepub',
    'Title',
    'localcurrency',
    'locations',
    'dropdown1',
    'dropdown2'
  ];
  var obj = {};
  var count = 1;
  var value;

  for (var i = 0; i < inputIds.length; i += 1) {
    value = $('#' + inputIds[i].toLowerCase()).val();
    if (value !== null && value !== '') {
      obj['FilterField' + count] = inputIds[i];
      obj['FilterValue' + count] = value;
      count += 1;
    }
  }

  console.log($.param(obj));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
Journal
<input type="text" id="journal" value="test & ampersand, comma, % percent, = equal and space" />
<br />keywords <input type="text" id="keywords" />

<br />datepub
<select id="datepub">
  <option value=""></option>
  <option value="1950">1950</option>
  <option value="2010">2010</option>
  <option value="2017" selected>2017</option>
  <option value="audi">Audi</option>
</select>
<br />title
<select id="title">
  <option value=""></option>
  <option value="TestDoc">test doc</option>
  <option value="t">t</option>
</select>
<br />localcurrency
<select id="localcurrency">
  <option value=""></option>
  <option value="USD">USD</option>
</select>
<br />locations
<select id="locations">
  <option value=""></option>
  <option value="US">US</option>
  <option value="UK">UK</option>
</select>
<br />dropdown1
<select id="dropdown1">
  <option value=""></option>
  <option value="a">a</option>
  <option value="b">b</option>
</select>
<br />dropdown2
<select id="dropdown2">
  <option value=""></option>
  <option value="aa">aa</option>
  <option value="bb">bb</option>
  <option value="cc">cc</option>
  <option value="dd">dd</option>
</select>
<br />
<button type="button" id="button">search</button>
<!-- re-used from https://stackoverflow.com/a/47008115/5108796 -->

BTW,通常不需要将字段名称作为值传递,只使用“field=value”。

但是您的后端处理可能有特定用例吗?

答案 1 :(得分:2)

扩展我的comment作为答案。

使用encodeURIComponent 不仅有效且正确,它实际上是URL中值的唯一支持特殊字符的修复,具有特殊含义URL。

在URL组件中编码值对于防止XSS攻击也很重要。看看here

  

URL转义很容易被双重转义,这意味着您必须   URL-将其零件正好转义一次。最好是执行   在汇编URL时进行URL转义。

但是,您可以通过以下方式改进代码

var inputs = [ "#journal", "#keywords", "#datepub", "#title", "#localcurrency", "#locations", "#dropdown1", "#dropdown2" ];
$(document).ready(function(){
    $('#button').click(function(e) {  
        var count =  1;
        var searchParams = inputs.filter( function( id ){
            return $( "#" + id ).val().trim().length > 0;
        }).map( function( id ){
            var value = encodeURIComponent( $( "#" + id ).val().trim() );
            return "FilterField" + (count) + "=" + id + "&FilterValue" + (count++) + "=" + value;
        }).join( "&" );
        window.location.replace("/teamsites/Bib%20Test/Forms/search.aspx?"+ searchParams );
    });
});

或者,您也可以使用URL(尽管not supported in IE

var inputs = [ "#journal", "#keywords", "#datepub", "#title", "#localcurrency", "#locations", "#dropdown1", "#dropdown2" ];
$(document).ready(function(){
    $('#button').click(function(e) {  
        var count =  1;
        var url = new URL( "/teamsites/Bib%20Test/Forms/search.aspx?", window.location.origin );        
        inputs.forEach( function( id ){
            var value = encodeURIComponent( $( "#" + id ).val().trim() );
            if ( value.length >  0 )
            {
                url.searchParams.append( "FilterField" + count, id );
                url.searchParams.append( "FilterValue" + (count++), value );
            }
        });
        window.location.replace( url.href );
    });
});

正如您所看到的,在这种方法中,您必须使用encodeURIcomponent,因为spec

  

append(name,value)方法在调用时必须运行以下步骤:

     

追加名称为name且value为value的新名称 - 值对   列表。

     

运行更新步骤。

无法保证将完成编码。 所以,必要的显式编码!!

答案 2 :(得分:1)

/!\这不是答案

与评论有关

const [
   $("#journal").val(),
   $("#keywords").val(),
   $("#datepub").val(),
   $("#title").val(),
   // ...
].forEach((x) => {
   if (x !== null && x !== '') {
     s += ...;

     count += 1;
   }
});

答案 3 :(得分:0)

我使用encodeUriComponent

url += "&filter=" + encodeURIComponent(filter);

你想要&#39;&amp;&#39;在要编码的参数值内,所以你使用&#39; encodeURIComponent&#39;关于参数的值,但是你不想在参数之间编码。

答案 4 :(得分:0)

如果您不关心Internet Explorer或Edge,请使用此选项。

我建议改用浏览器URL API。它是稳定的,并且在大多数现代浏览器中都可用于本地处理URL特定的工作。

您可以按照以下方式更改代码以使用此API。它根据规范自动编码所有必需的参数。您无需手动处理查询参数。

$(document).ready(function() {

  $('#button').click(function(e) {
    var count = 1;
    var s = "";
    var url = new URL("http://yourhost.com/teamsites/Bib%20Test/Forms/search.aspx");

    var inputvalue = $("#journal").val();
    var inputvalue2 = $("#keywords").val();
    var inputvalue3 = $("#datepub").val();
    var inputvalue4 = $("#title").val();
    var inputvalue5 = $("#localcurrency").val();
    var inputvalue6 = $("#locations").val();
    var inputvalue7 = $("#dropdown1").val();
    var inputvalue8 = $("#dropdown2").val();

    if (inputvalue != null && inputvalue != "") {
      url.searchParams.set("FilterField" + count, "Journal");
      url.searchParams.set("FilterValue" + count, inputvalue);
      count++;
    }

    if (inputvalue2 != null && inputvalue2 != "") {
      url.searchParams.set("FilterField" + count, "KeyWords");
      url.searchParams.set("FilterValue" + count, inputvalue2);
      count++;
    }

    if (inputvalue3 != null && inputvalue3 != "") {
      url.searchParams.set("FilterField" + count, "datepub");
      url.searchParams.set("FilterValue" + count, inputvalue3);
      count++;
    }

    if (inputvalue4 != null && inputvalue4 != "") {
      url.searchParams.set("FilterField" + count, "Title");
      url.searchParams.set("FilterValue" + count, inputvalue4);
      count++;
    }

    if (inputvalue5 != null && inputvalue5 != "") {
      url.searchParams.set("FilterField" + count, "localcurrency");
      url.searchParams.set("FilterValue" + count, inputvalue5);
      count++;
    }

    if (inputvalue6 != null && inputvalue6 != "") {
      url.searchParams.set("FilterField" + count, "locations");
      url.searchParams.set("FilterValue" + count, inputvalue6);
      count++;
    }

    if (inputvalue7 != null && inputvalue7 != "") {
      url.searchParams.set("FilterField" + count, "dropdown1");
      url.searchParams.set("FilterValue" + count, inputvalue7);
      count++;
    }

    if (inputvalue8 != null && inputvalue8 != "") {
      url.searchParams.set("FilterField" + count, "dropdown2");
      url.searchParams.set("FilterValue" + count, inputvalue8);
      count++;
    }

    window.location.replace(url.href);

  });
});

除此之外,我建议加入来自@GrégoryNEUT的建议,因为它使代码简洁易读。