How to POST to HTTPs?

google-chrome, html, internet-explorer-9

Solution

you can change the form's action with javascript:

var form = document.getElementById("post-form");
form.action = location.href.replace(/^http:/, 'https:');

But there are some security considerations, and I would suggest you to redirect your form's url to https. And although you could do it from javascript, you should never trust javascript when it gets to security, so do it from the server (it's also faster, the page doesn't have to be loaded, only the http header)

Problem

Assume i have a form that right now is doing a post: ``` <form id="post-form" class="post-form" action="/questions/ask/submit" method="post"> ``` You'll notice there is no site in the `action`, the browser follows where it got the page from. The browser follows current domain rules when posting ``` If the current page is... then the browser will POST to ======================================= ============= http://stackoverflow.com/questions/ask http://stackoverflow.com/questions/ask/submit https://stackoverflow.com/questions/ask https://stackoverflow.com/questions/ask/submit ``` But I want to ensure that the browser will always go to the secure page: ``` http://stackoverflow.com/questions/ask https://stackoverflow.com/questions/ask/submit ``` Normally you would try something like: ``` <form id="post-form" class="post-form" action="https://stackoverflow.com/questions/ask/submit" method="post"> ``` Except that requires knowing the domain and virtual path name of hosting site (e.g. `stackoverflow.com`). If the site were changed: - `stackoverflow.net` - `stackoverflow.com/mobile` - `de.stackoverflow.com` - `stackoverflow.co.uk/fr` - `beta.stackoverflow.com` then the form `action` would have to be updated also: ``` <form id="post-form" class="post-form" action="https://stackoverflow.net/questions/ask/submit" method="post"> <form id="post-form" class="post-form" action="https://stackoverflow.com/mobile/questions/ask/submit" method="post"> <form id="post-form" class="post-form" action="https://de.stackoverflow.com/questions/ask/submit" method="post"> <form id="post-form" class="post-form" action="https://stackoverflow.co.uk/fr/questions/ask/submit" method="post"> <form id="post-form" class="post-form" action="https://beta.stackoverflow.com/questions/ask/submit" method="post"> ``` How can I instruct the browser to go to `https` version of a page? Hypothetical syntax: ``` <form id="post-form" class="post-form" action="https://./questions/ask/submit" method="post"> ``` 302, 303, 307 Originally `302 Found` was the code to tell the user agent to go someplace else. The intention was that browsers would simply try again at the new location: ``` POST /questions/ask/submit 302 Found Location: /submitquestion POST /submitquestion ``` Unfortunately all browsers got it wrong, and would mistakenly always use `GET` on the new location: ``` POST /questions/ask/submit 302 Found Location: /submitquestion GET /submitquestion ``` Because browsers got it wrong, two new codes were created: - `302 Found`: (Legacy deprecated) Try the exact same thing again at the new location; but legacy browsers were switching to `GET` - `303 See Other`: Forget whatever the user was doing, and go do a `GET` on this Location - `307 Temporary Redirect`: Try the exact same thing again at the new Location (No, seriously, the same thing - i didn't say you could switch to `GET`. If you were doing a `DELETE` then go `DELETE` it over here.) For example, if the user agent was in the middle of a `POST`: ``` | Response | What agent should do | What many agents actually do | |------------------------|-----------------------|------------------------------| | 302 Found | POST to new Location | GET from new Location | | 303 See Other | GET from new Location | GET from new Location | | 307 Temporary Redirect | POST to new Location | POST to new Location | ``` Ideally, there would be a way to use `307 Temporary Redirect` to tell the user agent to try the `POST` again on the secure URL: ``` POST /questions/ask/submit 307 Temporary Redirect Location: https://beta.stackoverflow.com/questions/ask/submit POST /questions/ask/submit ``` and i can get away with that well enough server-side in ASP.net: ``` if (!Request.IsSecureConnection) { string redirectUrl = Request.Url.ToString().Replace("http:", "https:"); Response.Redirect(redirectUrl); //We don't want to send the client the deprecated 302 code, we want to use 307 telling them that we really want them to continue the POST, PUT, DELETE, etc Response.StatusCode = (int)System.Net.HttpStatusCode.TemporaryRedirect; Response.End(); } ``` But i don't know if you can specify a full uri in a `Location`.

Original source

Related problems