0

I have a html form - method="get" is obligatory in my case :

<form action="https://websiteurl.com/searchresult" method="get" id="bookingform"> 
<input type="hidden" name="hidden_field_1" value="val1"> 
<input type="hidden" name="hidden_field_2" value="val2"> 
<input id="checkin" type="text" name="checkin" value="">
<input id="checkout" type="text" name="checkin" value="">
<input type="submit" id="search" value="search">
</form>

submitting the form the resulting action URL looks like: https://websiteurl.com/searchresult?checkin=07%2F08%2F2025&checkout=08%2F08%2F2025&hidden_field_1=val1&hidden_field_2=val2

What I need to achieve is encode all the & and = in the resulting URL, all & should become %26 and all = %3D

so the final action URL should look like: https://websiteurl.com/searchresult?checkin%3D2025-11-05&checkout%3D2025-11-12%26hidden_field_1%3Dval1%26hidden_field_2%3Dval2

thank you in advance for any help

8
  • 2
    "What I need to achieve is encode all the & and = in the resulting URL" Why? This is would be non-standard behaviour. Commented Aug 7 at 11:17
  • Because is the only accepted format in my case... Commented Aug 7 at 11:20
  • 4
    Yes but, I would think there should be a technical reason as to why, not just "because". Commented Aug 7 at 11:22
  • 1
    Anyway, if you insist on not following the standards, you'll have to intercept the form submission and rewrite the URL before submitting to the backend. Commented Aug 7 at 11:24
  • 1
    For clarity, do you want to only encode the = and the data, e.g. foo=h@llo&bar=world$ becomes foo%3Dh%40llo%26bar%3Dworld%24. Or should it be double encoded, so the payload becomes foo%3Dh%2540llo%26bar%3Dworld%252? Commented Aug 7 at 11:51

2 Answers 2

1

A form with a "GET" action will grab the form data and format it as query parameters then navigate to the page were the action attribute points to.

This can be emulated easily by hand. Demonstration:

document.querySelector("form")
  .addEventListener("submit", (event) => {
    //do not navigate automatically
    event.preventDefault();
    
    customSubmit(event);
  });

function customSubmit(event) {
    //get the form data from the submitted form
    const form = event.target.closest("form");
    const formData = new FormData(form);
    
    //convert to URL search params to handle the data as appropriate
    const urlSearchParams = new URLSearchParams(formData);
    
    const payload = urlSearchParams.toString();
    
    console.log("payload:", payload);
    
    //create the destination URL
    const destination = new URL(form.action);
    destination.search = payload;
    
    console.log("navigating to:", destination.toString());

    //do not actually navigate for the demo but this is how it works:
    //location.href = destination;
    //alternatively to send the data without navigating:
    //fetch(destination)
}
<form action="https://websiteurl.com/searchresult" method="get" id="bookingform">
  <input type="hidden" name="hidden_field_1" value="val1">
  <input type="hidden" name="hidden_field_2" value="val2">
  <input id="checkin" type="text" name="checkin" value="h@llo">
  <input id="checkout" type="text" name="checkin" value="world$">
  <input type="submit" id="search" value="search">
</form>

The only change needed is to add custom encoding:

return urlSearchParams.toString()
  //use an encoded =
  .replaceAll("=", encodeURIComponent("="))
  //use an encoded &
  .replaceAll("&", encodeURIComponent("&"));

document.querySelector("form")
  .addEventListener("submit", (event) => {
    //do not navigate automatically
    event.preventDefault();
    
    customSubmit(event);
  });

function customSubmit(event) {
    //get the form data from the submitted form
    const form = event.target.closest("form");
    const formData = new FormData(form);
    
    //convert to URL search params to handle the data as appropriate
    const urlSearchParams = new URLSearchParams(formData);
    
    //do a custom conversion to also encode the & and = characters
    const payload = customConvert(urlSearchParams);
    
    console.log("payload:", payload);
    
    //create the destination URL
    const destination = new URL(form.action);
    destination.search = payload;
    
    console.log("navigating to:", destination.toString());

    //do not actually navigate for the demo but this is how it works:
    //location.href = destination;
    //alternatively to send the data without navigating:
    //fetch(destination)
}
  
function customConvert(urlSearchParams) {
  return urlSearchParams.toString()
    //use an encoded =
    .replaceAll("=", encodeURIComponent("="))
    //use an encoded &
    .replaceAll("&", encodeURIComponent("&"));
}
<form action="https://websiteurl.com/searchresult" method="get" id="bookingform">
  <input type="hidden" name="hidden_field_1" value="val1">
  <input type="hidden" name="hidden_field_2" value="val2">
  <input id="checkin" type="text" name="checkin" value="h@llo">
  <input id="checkout" type="text" name="checkin" value="world$">
  <input type="submit" id="search" value="search">
</form>

This works because there is guarantee that there would be no other = and & characters in the encoded URL search parameters string. If there were any, they would have been encoded already URL encoded:

const searchParams = new URLSearchParams({
  "f=oo": "he&llo",
  "b&ar": "wo=rld",
});

console.log(searchParams.toString());

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much VLAZ, I'll give it a try
Although this appears to answer OPs question, the problem comes when attempting to unencode the query string as special characters in the inputs could be confused with delimiters in the query string, An extra & in an input value would probably result in a loss of information. Taking the third example f%3Doo=he%26llo&b%26ar=wo%3Drld would be encoded to f%3Doo%3Dhe%26llo%26b%26ar%3Dwo%3Drld and presumably would have to be decoded at some point resulting in f=oo=he&llo&b&ar=wo=rld. Good luck trying to figure out what it should have been.
-1
document.getElementById('bookingform').addEventListener('submit', function (e) {
  e.preventDefault(); // prevent default form submission

  const form = e.target;
  const formData = new FormData(form);
  const params = [];

  for (const [key, value] of formData.entries()) {
    // Encode key and value
    const encodedKey = encodeURIComponent(key);
    const encodedValue = encodeURIComponent(value);
    // Join as as key + = + value
    params.push(encodedKey + '%3D' + encodedValue); 
    // equivalent to key = value but the equal is change to %3D so key + %3D + value
  }

 // .join function is use to join array string, and the parameter will be the one to join them   param1&param2 = param1%26param2
  const encodedQuery = params.join('%26');
  const targetURL = 'https://websiteurl.com/searchresult?' + encodedQuery;

  // Redirect manually
  window.location.href = targetURL;
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.