【问题标题】:How to POST to HTTPs?如何发布到 HTTPs?
【发布时间】:2012-05-11 06:58:54
【问题描述】:

假设我有一个表格,现在正在发帖:

<form id="post-form" class="post-form" 
      action="/questions/ask/submit" method="post">

您会注意到action 中没有站点,浏览器会跟随它获取页面的位置。

浏览器在发布时遵循当前的域规则

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

但我想确保浏览器始终会转到安全页面:

http://stackoverflow.com/questions/ask   https://stackoverflow.com/questions/ask/submit

通常你会尝试这样的事情:

<form id="post-form" class="post-form" 
      action="https://stackoverflow.com/questions/ask/submit" method="post">

除非需要知道托管站点的域和虚拟路径名(例如stackoverflow.com)。如果网站已更改:

  • stackoverflow.net
  • stackoverflow.com/mobile
  • de.stackoverflow.com
  • stackoverflow.co.uk/fr
  • beta.stackoverflow.com

那么action 的表单也必须更新:

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

如何指示浏览器转到https 版本的页面


假设语法:

<form id="post-form" class="post-form" action="https://./questions/ask/submit" method="post">

302、303、307

最初302 Found 是告诉用户代理去其他地方的代码。其目的是让浏览器在新位置再次尝试:

POST /questions/ask/submit

302 Found
Location: /submitquestion

POST /submitquestion

不幸的是所有浏览器都弄错了,并且总是错误地在新位置上使用GET

POST /questions/ask/submit

302 Found
Location: /submitquestion

GET /submitquestion

因为浏览器弄错了,所以创建了两个新代码:

  • 302 Found(不推荐使用旧版) 在新位置再次尝试完全相同的操作;但旧版浏览器正在切换到GET
  • 303 See Other:忘记用户在做什么,去这个位置GET
  • 307 Temporary Redirect: 在新的位置再试一次完全相同的事情(不,说真的,同样的事情——我没说你可以切换到GET。如果你正在做一个DELETE,那么请到这里去DELETE。)

例如,如果用户代理位于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         |

理想情况下,有一种方法可以使用 307 Temporary Redirect 告诉用户代理在安全 URL 上再次尝试 POST

POST /questions/ask/submit

307 Temporary Redirect
Location: https://beta.stackoverflow.com/questions/ask/submit

POST /questions/ask/submit

我可以在 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();
}

但我不知道您是否可以在 Location 中指定完整的 uri。

【问题讨论】:

  • 你试过这个吗:stackoverflow.com/questions/4398951/…
  • @j08691 我发生进入 ASP.net;但我希望有一个独立于服务器(即客户端)的解决方案。
  • 在 Apache 中,我猜可能有一种方法可以使用当前目录中的 .htaccess 文件来执行此操作。或者肯定可以用 PHP 或 ASP 或其他服务器语言构建。

标签: html google-chrome internet-explorer-9


【解决方案1】:

您最好确保如果用户已经登陆您的 http 页面,您将他重定向到 https 等价物。 在你的:

<script>
if ((window.location.href.substring(0, 8) != "https://") {
  window.location = location.href.replace(/^http:/, 'https:');
}
</script>

【讨论】:

    【解决方案2】:

    您可以使用 javascript 更改表单的操作:

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

    但是有一些security considerations,我建议您将表单的网址重定向到https。虽然你可以通过 javascript 来做,但你永远不应该信任 javascript,因为它涉及到安全性,所以从服务器上做(它也更快,页面不需要加载,只有 http 标头)

    【讨论】:

    • 这仍然需要我将提交操作从 "/questions/ask/submit" 更改为 "http://beta.de.stackoverflow.net/mobile/questions/ask/submit" :(
    • 然后将该 base_url 保存在某处。你也许可以使用 ,但如果它有不好的副作用,那么只需将它打印到一个 javascript 变量中: var baseUrl = "beta.de.stackoverflow.net/mobile/";那么你可以连接 form.action = "https://" + baseurl + form.action,或者你可以只使用 location.hostname。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2012-07-15
    • 2013-10-07
    • 2015-02-27
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多