0

I have an <input type="text"> and i would like to set it's value to the "q" query string safely. Because if the query string contains a special character (+,#,...) , the JS will stop executing.

I have tried encodeURIComponent() and encodeURI(), but the value in the search box will also be escaped, so you'll get some weird things in the search box.

I also tried decodeURIComponent(encodeURIComponent()) but this will make the JS stop executing.

Also, PHP isn't the solution I want to use, so let's forget PHP GET even if it works.

Try the bug : http://smartsearch.altervista.org/?q=the+plus+character+breaks+the+code

And as you can see the panels don't work anymore (click on the toolbar buttons, they should show a panel). The panels work perfectly when there's no query strings with special characters.

Full code (as some people requested it) :

$(function() {
if(getParameter("q") && getParameter("engine")) {
        search(getParameter("q").replace("smartsearch://",""),getParameter("engine"));
    }
    else if(getParameter("engine")) {
        $(".search-engine a[data-engine-shortname="+getParameter("engine")+"]").click();
    }
    else if(getParameter("q")) {
        search(getParameter("q").replace("smartsearch://",""));
    }
    });
// Helper functions
function getParameter(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function search(query,engine) {
    var searchengine = engine || $(".search-engine.selected a").attr("data-engine-shortname");
    var searchengineurl = $(".search-engine a[data-engine-shortname="+engine+"]").attr("data-engine-url") || $("#search-form").attr("action");
    var searchquery = query || $("#search-input").val();
    var currenturl = "?q=" + searchquery.split(' ').join('+') + "&engine=" + searchengine;
    var icon = $(".search-engine a[data-engine-shortname="+engine+"] img").attr("src") || $(".search-engine.selected a img").attr("src");
    if($.trim(searchquery) != "") {
        $("#results-frame").attr("src",searchengineurl + searchquery);
        $("title").html(searchquery + " - SmartSearch");
        history.replaceState(null, null, currenturl);
        if(engine) {
            $(".search-engine a[data-engine-shortname="+engine+"]").click();
        }
        $("#search-input").val(searchquery);
        $("#favourite-button").removeClass("starred disabled");
        if(bookmarks.check(searchquery,searchengine)) {
            $("#favourite-button").addClass("starred");
        }
    }
    else {
        $("title").html("SmartSearch");
        $("#favourite-button").addClass("disabled");
        $("#favourite-button").removeClass("starred");
        if(bookmarks.check(searchquery,searchengine)) {
            $("#favourite-button").addClass("starred");
        }
    }
}
Tim Nguyen
  • 1,163
  • 10
  • 21

1 Answers1

0

If you refer the section of https://www.rfc-editor.org/rfc/rfc3986#section-2.2

 reserved    = gen-delims / sub-delims

 gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

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

The RFC goes on to say

If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed.

Community
  • 1
  • 1
Tito
  • 8,894
  • 12
  • 52
  • 86
  • So what should i do before is : window.location.href = encodeURI(window.location.href) ? – Tim Nguyen Nov 05 '13 at 19:20
  • You should use percent encoding , that is "foo#bar foobar" will be converted to "foo%23bar+foobar". Here is more info on best practice for using encodeURI --> http://stackoverflow.com/questions/75980/best-practice-escape-or-encodeuri-encodeuricomponent – Tito Nov 05 '13 at 19:26
  • Just tried this for percent encoding : `history.replaceState(null,null,encodeURIComponent(window.location.search));` but it doesn't seem to work, the search field is empty instead. – Tim Nguyen Nov 05 '13 at 19:29