Response.Redirect 使用 POST 而不是 Get?

发布于 2024-07-04 10:20:37 字数 312 浏览 11 评论 0原文

我们需要提交表单并保存一些数据,然后将用户重定向到异地页面,但在重定向中,我们需要使用 POST 来“提交”表单,而不是 GET。

我希望有一种简单的方法可以实现这一点,但我开始认为没有。 我想我现在必须创建一个简单的其他页面,其中只有我想要的表单,重定向到它,填充表单变量,然后对仅调用 document.forms[0].submit( );

谁能告诉我是否有替代方案? 我们可能需要在项目后期对此进行调整,并且可能会变得有点复杂,因此如果有一个简单的方法,我们可以完成所有非其他页面依赖的工作,那就太棒了。

无论如何,感谢您的所有回复。

We have the requirement to take a form submission and save some data, then redirect the user to a page offsite, but in redirecting, we need to "submit" a form with POST, not GET.

I was hoping there was an easy way to accomplish this, but I'm starting to think there isn't. I think I must now create a simple other page, with just the form that I want, redirect to it, populate the form variables, then do a body.onload call to a script that merely calls document.forms[0].submit();

Can anyone tell me if there is an alternative? We might need to tweak this later in the project, and it might get sort of complicated, so if there was an easy we could do this all non-other page dependent that would be fantastic.

Anyway, thanks for any and all responses.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

惯饮孤独 2024-07-11 10:20:37

这应该会让生活变得更轻松。
您可以轻松地在 Web 应用程序中使用 Response.RedirectWithData(...) 方法。

Imports System.Web
Imports System.Runtime.CompilerServices

Module WebExtensions

    <Extension()> _
    Public Sub RedirectWithData(ByRef aThis As HttpResponse, ByVal aDestination As String, _
                                ByVal aData As NameValueCollection)
        aThis.Clear()
        Dim sb As StringBuilder = New StringBuilder()

        sb.Append("<html>")
        sb.AppendFormat("<body onload='document.forms[""form""].submit()'>")
        sb.AppendFormat("<form name='form' action='{0}' method='post'>", aDestination)

        For Each key As String In aData
            sb.AppendFormat("<input type='hidden' name='{0}' value='{1}' />", key, aData(key))
        Next

        sb.Append("</form>")
        sb.Append("</body>")
        sb.Append("</html>")

        aThis.Write(sb.ToString())

        aThis.End()
    End Sub

End Module

This should make life much easier.
You can simply use Response.RedirectWithData(...) method in your web application easily.

Imports System.Web
Imports System.Runtime.CompilerServices

Module WebExtensions

    <Extension()> _
    Public Sub RedirectWithData(ByRef aThis As HttpResponse, ByVal aDestination As String, _
                                ByVal aData As NameValueCollection)
        aThis.Clear()
        Dim sb As StringBuilder = New StringBuilder()

        sb.Append("<html>")
        sb.AppendFormat("<body onload='document.forms[""form""].submit()'>")
        sb.AppendFormat("<form name='form' action='{0}' method='post'>", aDestination)

        For Each key As String In aData
            sb.AppendFormat("<input type='hidden' name='{0}' value='{1}' />", key, aData(key))
        Next

        sb.Append("</form>")
        sb.Append("</body>")
        sb.Append("</html>")

        aThis.Write(sb.ToString())

        aThis.End()
    End Sub

End Module
凉墨 2024-07-11 10:20:37

HttpWebRequest 用于此目的。

在回发时,创建一个 HttpWebRequest 到您的第三方并发布表单数据,然后一旦完成,您就可以 Response.Redirect 到任何您想要的地方。

您可以获得额外的优势,即您不必命名所有服务器控件来创建第 3 方表单,您可以在构建 POST 字符串时进行此转换。

string url = "3rd Party Url";

StringBuilder postData = new StringBuilder();

postData.Append("first_name=" + HttpUtility.UrlEncode(txtFirstName.Text) + "&");
postData.Append("last_name=" + HttpUtility.UrlEncode(txtLastName.Text));

//ETC for all Form Elements

// Now to Send Data.
StreamWriter writer = null;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";                        
request.ContentLength = postData.ToString().Length;
try
{
    writer = new StreamWriter(request.GetRequestStream());
    writer.Write(postData.ToString());
}
finally
{
    if (writer != null)
        writer.Close();
}

Response.Redirect("NewPage");

但是,如果您需要用户从此表单中查看响应页面,您唯一的选择是使用 Server.Transfer,这可能有效,也可能无效。

HttpWebRequest is used for this.

On postback, create a HttpWebRequest to your third party and post the form data, then once that is done, you can Response.Redirect wherever you want.

You get the added advantage that you don't have to name all of your server controls to make the 3rd parties form, you can do this translation when building the POST string.

string url = "3rd Party Url";

StringBuilder postData = new StringBuilder();

postData.Append("first_name=" + HttpUtility.UrlEncode(txtFirstName.Text) + "&");
postData.Append("last_name=" + HttpUtility.UrlEncode(txtLastName.Text));

//ETC for all Form Elements

// Now to Send Data.
StreamWriter writer = null;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";                        
request.ContentLength = postData.ToString().Length;
try
{
    writer = new StreamWriter(request.GetRequestStream());
    writer.Write(postData.ToString());
}
finally
{
    if (writer != null)
        writer.Close();
}

Response.Redirect("NewPage");

However, if you need the user to see the response page from this form, your only option is to utilize Server.Transfer, and that may or may not work.

樱花细雨 2024-07-11 10:20:37

ASP.Net 3.5 中的新功能是 ASP 按钮的“PostBackUrl”属性。 您可以将其设置为您想要直接发布到的页面的地址,当单击该按钮时,它不会像平常一样发布回同一页面,而是发布到您指定的页面。 便利。 确保 UseSubmitBehavior 也设置为 TRUE。

Something new in ASP.Net 3.5 is this "PostBackUrl" property of ASP buttons. You can set it to the address of the page you want to post directly to, and when that button is clicked, instead of posting back to the same page like normal, it instead posts to the page you've indicated. Handy. Be sure UseSubmitBehavior is also set to TRUE.

可是我不能没有你 2024-07-11 10:20:37

我想分享一下 Heroku 通过它的 SSO 到附加提供程序来实现这一点可能会很有趣。

它如何工作的示例可以在“kensa”工具的源代码中看到:

https://github.com/heroku/kensa/blob/d4a56d50dcbebc2d26a4950081acda988937ee10/lib/heroku/肯萨/post_proxy.rb< /a>

如果你关闭 javascript,可以在实践中看到。 示例页面来源:

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Heroku Add-ons SSO</title>
  </head>

  <body>
    <form method="POST" action="https://XXXXXXXX/sso/login">

        <input type="hidden" name="email" value="XXXXXXXX" />

        <input type="hidden" name="app" value="XXXXXXXXXX" />

        <input type="hidden" name="id" value="XXXXXXXX" />

        <input type="hidden" name="timestamp" value="1382728968" />

        <input type="hidden" name="token" value="XXXXXXX" />

        <input type="hidden" name="nav-data" value="XXXXXXXXX" />

    </form>

    <script type="text/javascript">
      document.forms[0].submit();
    </script>
  </body>
</html>

Thought it might interesting to share that heroku does this with it's SSO to Add-on providers

An example of how it works can be seen in the source to the "kensa" tool:

https://github.com/heroku/kensa/blob/d4a56d50dcbebc2d26a4950081acda988937ee10/lib/heroku/kensa/post_proxy.rb

And can be seen in practice if you turn of javascript. Example page source:

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Heroku Add-ons SSO</title>
  </head>

  <body>
    <form method="POST" action="https://XXXXXXXX/sso/login">

        <input type="hidden" name="email" value="XXXXXXXX" />

        <input type="hidden" name="app" value="XXXXXXXXXX" />

        <input type="hidden" name="id" value="XXXXXXXX" />

        <input type="hidden" name="timestamp" value="1382728968" />

        <input type="hidden" name="token" value="XXXXXXX" />

        <input type="hidden" name="nav-data" value="XXXXXXXXX" />

    </form>

    <script type="text/javascript">
      document.forms[0].submit();
    </script>
  </body>
</html>
十年九夏 2024-07-11 10:20:37

可以在您的 asp 按钮上设置 PostbackUrl 以发布到不同的页面。

如果您需要在代码隐藏中执行此操作,请尝试 Server.Transfer。

PostbackUrl can be set on your asp button to post to a different page.

if you need to do it in codebehind, try Server.Transfer.

腹黑女流氓 2024-07-11 10:20:37

@Matt,

您仍然可以使用 HttpWebRequest,然后将收到的响应定向到实际的输出流响应,这会将响应返回给用户。 唯一的问题是任何相对网址都会被破坏。

不过,这可能有效。

@Matt,

You can still use the HttpWebRequest, then direct the response you receive to the actual outputstream response, this would serve the response back to the user. The only issue is that any relative urls would be broken.

Still, that may work.

梦一生花开无言 2024-07-11 10:20:37

我建议构建一个 HttpWebRequest 以编程方式执行您的 POST,然后在读取响应(如果适用)后进行重定向。

I suggest building an HttpWebRequest to programmatically execute your POST and then redirect after reading the Response if applicable.

温柔戏命师 2024-07-11 10:20:37

这就是我要做的:

将数据放入标准表单(没有 runat="server" 属性),并将表单的操作设置为发布到目标场外页面。
在提交之前,我将使用 XmlHttpRequest 将数据提交到我的服务器并分析响应。 如果响应意味着您应该继续进行异地发布,那么我(JavaScript)将继续发布,否则我将重定向到我网站上的页面

Here's what I'd do :

Put the data in a standard form (with no runat="server" attribute) and set the action of the form to post to the target off-site page.
Before submitting I would submit the data to my server using an XmlHttpRequest and analyze the response. If the response means you should go ahead with the offsite POSTing then I (the JavaScript) would proceed with the post otherwise I would redirect to a page on my site

郁金香雨 2024-07-11 10:20:37

在 PHP 中,您可以使用 cURL 发送 POST 数据。 有与 .NET 类似的东西吗?

是的,HttpWebRequest,请参阅下面我的帖子。

In PHP, you can send POST data with cURL. Is there something comparable for .NET?

Yes, HttpWebRequest, see my post below.

硪扪都還晓 2024-07-11 10:20:37

GET(和 HEAD)方法永远不应该被用来做任何有副作用的事情。 副作用可能是更新 Web 应用程序的状态,或者可能是向您的信用卡收费。 如果某个操作有副作用,则应使用另一种方法 (POST)。

因此,用户(或他们的浏览器)不应该对 GET 所做的事情负责。 如果 GET 的结果发生了一些有害或昂贵的副作用,那将是 Web 应用程序的错误,而不是用户的错误。 根据规范,用户代理不得自动遵循重定向,除非它是对 GET 或 HEAD 请求的响应。

当然,许多 GET 请求确实有一些副作用,即使它只是附加到日志文件中。 重要的是应用程序而不是用户应对这些影响负责。

HTTP 规范的相关部分是 9.1.1 和 9.1.210.3

The GET (and HEAD) method should never be used to do anything that has side-effects. A side-effect might be updating the state of a web application, or it might be charging your credit card. If an action has side-effects another method (POST) should be used instead.

So, a user (or their browser) shouldn't be held accountable for something done by a GET. If some harmful or expensive side-effect occurred as the result of a GET, that would be the fault of the web application, not the user. According to the spec, a user agent must not automatically follow a redirect unless it is a response to a GET or HEAD request.

Of course, a lot of GET requests do have some side-effects, even if it's just appending to a log file. The important thing is that the application, not the user, should be held responsible for those effects.

The relevant sections of the HTTP spec are 9.1.1 and 9.1.2, and 10.3.

自演自醉 2024-07-11 10:20:37

通常,您所需要的只是在这两个请求之间携带一些状态。 实际上有一种非常时髦的方法可以做到这一点,它不依赖于 JavaScript(想想

Set-Cookie: name=value; Max-Age=120; Path=/redirect.html

有了该 cookie,您就可以在以下对 /redirect.html 的请求中检索 name=value 信息,您可以在此名称/值对字符串中存储任何类型的信息,最多可存储 4K 数据(典型的 cookie 限制)。 当然,您应该避免这种情况并存储状态代码和标志位。

收到此请求后,您会回复该状态代码的删除请求。

Set-Cookie: name=value; Max-Age=0; Path=/redirect.html

我的 HTTP 有点生疏,我一直在研究 RFC2109 和 RFC2965 来弄清楚这到底有多可靠,最好我希望 cookie 只往返一次,但这似乎也是不可能的,第三如果您要迁移到另一个域,-party cookies 可能会给您带来问题。 这仍然是可能的,但不像您在自己的域中执行操作时那样轻松。

这里的问题是并发性,如果高级用户使用多个选项卡并设法交错属于同一域的几个请求session(这不太可能,但并非不可能)这可能会导致应用程序中的不一致。

这是

我提供此代码作为概念教授:如果此代码在您不熟悉的上下文中运行,我认为您可以弄清楚哪个部分是什么。

这个想法是,您在重定向时调用带有某种状态的 Relocate,并且您重新定位的 URL 调用 GetState 来获取数据(如果有)。

const string StateCookieName = "state";

static int StateCookieID;

protected void Relocate(string url, object state)
{
    var key = "__" + StateCookieName + Interlocked
        .Add(ref StateCookieID, 1).ToInvariantString();

    var absoluteExpiration = DateTime.Now
        .Add(new TimeSpan(120 * TimeSpan.TicksPerSecond));

    Context.Cache.Insert(key, state, null, absoluteExpiration,
        Cache.NoSlidingExpiration);

    var path = Context.Response.ApplyAppPathModifier(url);

    Context.Response.Cookies
        .Add(new HttpCookie(StateCookieName, key)
        {
            Path = path,
            Expires = absoluteExpiration
        });

    Context.Response.Redirect(path, false);
}

protected TData GetState<TData>()
    where TData : class
{
    var cookie = Context.Request.Cookies[StateCookieName];
    if (cookie != null)
    {
        var key = cookie.Value;
        if (key.IsNonEmpty())
        {
            var obj = Context.Cache.Remove(key);

            Context.Response.Cookies
                .Add(new HttpCookie(StateCookieName)
                { 
                    Path = cookie.Path, 
                    Expires = new DateTime(1970, 1, 1) 
                });

            return obj as TData;
        }
    }
    return null;
}

Typically, all you'll ever need is to carry some state between these two requests. There's actually a really funky way to do this which doesn't rely on JavaScript (think <noscript/>).

Set-Cookie: name=value; Max-Age=120; Path=/redirect.html

With that cookie there, you can in the following request to /redirect.html retrieve the name=value info, you can store any kind of information in this name/value pair string, up to say 4K of data (typical cookie limit). Of course you should avoid this and store status codes and flag bits instead.

Upon receiving this request you in return respond with a delete request for that status code.

Set-Cookie: name=value; Max-Age=0; Path=/redirect.html

My HTTP is a bit rusty I've been going trough RFC2109 and RFC2965 to figure how reliable this really is, preferably I would want the cookie to round trip exactly once but that doesn't seem to be possible, also, third-party cookies might be a problem for you if you are relocating to another domain. This is still possible but not as painless as when you're doing stuff within your own domain.

The problem here is concurrency, if a power user is using multiple tabs and manages to interleave a couple of requests belonging to the same session (this is very unlikely, but not impossible) this may lead to inconsistencies in your application.

It's the <noscript/> way of doing HTTP round trips without meaningless URLs and JavaScript

I provide this code as a prof of concept: If this code is run in a context that you are not familiar with I think you can work out what part is what.

The idea is that you call Relocate with some state when you redirect, and the URL which you relocated calls GetState to get the data (if any).

const string StateCookieName = "state";

static int StateCookieID;

protected void Relocate(string url, object state)
{
    var key = "__" + StateCookieName + Interlocked
        .Add(ref StateCookieID, 1).ToInvariantString();

    var absoluteExpiration = DateTime.Now
        .Add(new TimeSpan(120 * TimeSpan.TicksPerSecond));

    Context.Cache.Insert(key, state, null, absoluteExpiration,
        Cache.NoSlidingExpiration);

    var path = Context.Response.ApplyAppPathModifier(url);

    Context.Response.Cookies
        .Add(new HttpCookie(StateCookieName, key)
        {
            Path = path,
            Expires = absoluteExpiration
        });

    Context.Response.Redirect(path, false);
}

protected TData GetState<TData>()
    where TData : class
{
    var cookie = Context.Request.Cookies[StateCookieName];
    if (cookie != null)
    {
        var key = cookie.Value;
        if (key.IsNonEmpty())
        {
            var obj = Context.Cache.Remove(key);

            Context.Response.Cookies
                .Add(new HttpCookie(StateCookieName)
                { 
                    Path = cookie.Path, 
                    Expires = new DateTime(1970, 1, 1) 
                });

            return obj as TData;
        }
    }
    return null;
}
酒与心事 2024-07-11 10:20:37

基于 Pavlo Neyman 方法 RedirectPost(string url, T bodyPayload) 和 GetPostData() 的可复制粘贴代码

适合那些只需要想要在源页面中转储一些强类型数据并将其取回到目标页面中。
数据必须可由 NewtonSoft Json.NET 序列化,当然您需要引用该库。

只需复制粘贴到您的页面或更好的页面基类中,然后在应用程序中的任何位置使用它。

我对所有在 2019 年因某种原因仍然需要使用 Web 表单的人表示同情。

        protected void RedirectPost(string url, IEnumerable<KeyValuePair<string,string>> fields)
        {
            Response.Clear();

            const string template =
@"<html>
<body onload='document.forms[""form""].submit()'>
<form name='form' action='{0}' method='post'>
{1}
</form>
</body>
</html>";

            var fieldsSection = string.Join(
                    Environment.NewLine,
                    fields.Select(x => $"<input type='hidden' name='{HttpUtility.UrlEncode(x.Key)}' value='{HttpUtility.UrlEncode(x.Value)}'>")
                );

            var html = string.Format(template, HttpUtility.UrlEncode(url), fieldsSection);

            Response.Write(html);

            Response.End();
        }

        private const string JsonDataFieldName = "_jsonData";

        protected void RedirectPost<T>(string url, T bodyPayload)
        {
            var json = JsonConvert.SerializeObject(bodyPayload, Formatting.Indented);
            //explicit type declaration to prevent recursion
            IEnumerable<KeyValuePair<string, string>> postFields = new List<KeyValuePair<string, string>>()
                {new KeyValuePair<string, string>(JsonDataFieldName, json)};

            RedirectPost(url, postFields);

        }

        protected T GetPostData<T>() where T: class 
        {
            var urlEncodedFieldData = Request.Params[JsonDataFieldName];
            if (string.IsNullOrEmpty(urlEncodedFieldData))
            {
                return null;// default(T);
            }

            var fieldData = HttpUtility.UrlDecode(urlEncodedFieldData);

            var result = JsonConvert.DeserializeObject<T>(fieldData);
            return result;
        }

Copy-pasteable code based on Pavlo Neyman's method

RedirectPost(string url, T bodyPayload) and GetPostData() are for those who just want to dump some strongly typed data in the source page and fetch it back in the target one.
The data must be serializeable by NewtonSoft Json.NET and you need to reference the library of course.

Just copy-paste into your page(s) or better yet base class for your pages and use it anywhere in you application.

My heart goes out to all of you who still have to use Web Forms in 2019 for whatever reason.

        protected void RedirectPost(string url, IEnumerable<KeyValuePair<string,string>> fields)
        {
            Response.Clear();

            const string template =
@"<html>
<body onload='document.forms[""form""].submit()'>
<form name='form' action='{0}' method='post'>
{1}
</form>
</body>
</html>";

            var fieldsSection = string.Join(
                    Environment.NewLine,
                    fields.Select(x => $"<input type='hidden' name='{HttpUtility.UrlEncode(x.Key)}' value='{HttpUtility.UrlEncode(x.Value)}'>")
                );

            var html = string.Format(template, HttpUtility.UrlEncode(url), fieldsSection);

            Response.Write(html);

            Response.End();
        }

        private const string JsonDataFieldName = "_jsonData";

        protected void RedirectPost<T>(string url, T bodyPayload)
        {
            var json = JsonConvert.SerializeObject(bodyPayload, Formatting.Indented);
            //explicit type declaration to prevent recursion
            IEnumerable<KeyValuePair<string, string>> postFields = new List<KeyValuePair<string, string>>()
                {new KeyValuePair<string, string>(JsonDataFieldName, json)};

            RedirectPost(url, postFields);

        }

        protected T GetPostData<T>() where T: class 
        {
            var urlEncodedFieldData = Request.Params[JsonDataFieldName];
            if (string.IsNullOrEmpty(urlEncodedFieldData))
            {
                return null;// default(T);
            }

            var fieldData = HttpUtility.UrlDecode(urlEncodedFieldData);

            var result = JsonConvert.DeserializeObject<T>(fieldData);
            return result;
        }
断爱 2024-07-11 10:20:37

您可以使用这种方法:

Response.Clear();

StringBuilder sb = new StringBuilder();
sb.Append("<html>");
sb.AppendFormat(@"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>",postbackUrl);
sb.AppendFormat("<input type='hidden' name='id' value='{0}'>", id);
// Other params go here
sb.Append("</form>");
sb.Append("</body>");
sb.Append("</html>");

Response.Write(sb.ToString());

Response.End();

当客户端从服务器获取所有 html 后,就会发生 onload 事件,触发表单提交并将所有数据发布到定义的 postbackUrl。

You can use this aproach:

Response.Clear();

StringBuilder sb = new StringBuilder();
sb.Append("<html>");
sb.AppendFormat(@"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>",postbackUrl);
sb.AppendFormat("<input type='hidden' name='id' value='{0}'>", id);
// Other params go here
sb.Append("</form>");
sb.Append("</body>");
sb.Append("</html>");

Response.Write(sb.ToString());

Response.End();

As result right after client will get all html from server the event onload take place that triggers form submit and post all data to defined postbackUrl.

甜尕妞 2024-07-11 10:20:37

执行此操作需要了解 HTTP 重定向的工作原理。 当您使用 Response.Redirect() 时,您将使用 HTTP 状态代码 302,告诉浏览器下一步该去哪里。 根据定义,浏览器将通过 GET 请求进行此操作,即使原始请求是 POST

另一种选择是使用 HTTP 状态代码 307,它指定浏览器应进行重定向请求方式与原始请求相同,但会提示用户安全警告。 为此,您可以编写如下内容:

public void PageLoad(object sender, EventArgs e)
{
    // Process the post on your side   
    
    Response.Status = "307 Temporary Redirect";
    Response.AddHeader("Location", "http://example.com/page/to/post.to");
}

不幸的是,这并不总是有效。 不同的浏览器对此的实现方式不同,因为这不是常见的状态代码。

唉,与 Opera 和 FireFox 开发人员不同,IE 开发人员从未阅读过规范,即使是最新、最安全的 IE7 也会将 POST 请求从域 A 重定向到域 B,而不会出现任何警告或确认对话框! Safari 的行为方式也很有趣,虽然它不会弹出确认对话框并执行重定向,但它会丢弃 POST 数据,有效地将 307 重定向更改为更常见的 302。

Safari 的行为方式 我知道,实现这样的事情的唯一方法是使用 Javascript。 我立即想到了两个选项:

  1. 创建表单并使其 action 属性指向第三方服务器。 然后,向提交按钮添加一个单击事件,该按钮首先使用数据向您的服务器执行 AJAX 请求,然后允许将表单提交到第三方服务器。
  2. 创建要发布到您的服务器的表单。 提交表单后,向用户显示一个页面,其中包含一个表单,其中包含您要传递的所有数据,所有数据都在隐藏输入中。 只需显示“正在重定向...”之类的消息。 然后,向将表单提交到第三方服务器的页面添加一个 javascript 事件。

在这两者中,我会选择第二个,原因有两个。 首先,它比第一个更可靠,因为它不需要 JavaScript 即可工作; 对于那些没有启用它的人,您可以随时使隐藏表单的提交按钮可见,并指示他们在需要超过 5 秒的时间时按下该按钮。 其次,您可以决定将哪些数据传输到第三方服务器; 如果您只使用处理表单,您将传递所有的发布数据,这并不总是您想要的。 307 解决方案也是如此,假设它适用于所有用户。

Doing this requires understanding how HTTP redirects work. When you use Response.Redirect(), you send a response (to the browser that made the request) with HTTP Status Code 302, which tells the browser where to go next. By definition, the browser will make that via a GET request, even if the original request was a POST.

Another option is to use HTTP Status Code 307, which specifies that the browser should make the redirect request in the same way as the original request, but to prompt the user with a security warning. To do that, you would write something like this:

public void PageLoad(object sender, EventArgs e)
{
    // Process the post on your side   
    
    Response.Status = "307 Temporary Redirect";
    Response.AddHeader("Location", "http://example.com/page/to/post.to");
}

Unfortunately, this won't always work. Different browsers implement this differently, since it is not a common status code.

Alas, unlike the Opera and FireFox developers, the IE developers have never read the spec, and even the latest, most secure IE7 will redirect the POST request from domain A to domain B without any warnings or confirmation dialogs! Safari also acts in an interesting manner, while it does not raise a confirmation dialog and performs the redirect, it throws away the POST data, effectively changing 307 redirect into the more common 302.

So, as far as I know, the only way to implement something like this would be to use Javascript. There are two options I can think of off the top of my head:

  1. Create the form and have its action attribute point to the third-party server. Then, add a click event to the submit button that first executes an AJAX request to your server with the data, and then allows the form to be submitted to the third-party server.
  2. Create the form to post to your server. When the form is submitted, show the user a page that has a form in it with all of the data you want to pass on, all in hidden inputs. Just show a message like "Redirecting...". Then, add a javascript event to the page that submits the form to the third-party server.

Of the two, I would choose the second, for two reasons. First, it is more reliable than the first because Javascript is not required for it to work; for those who don't have it enabled, you can always make the submit button for the hidden form visible, and instruct them to press it if it takes more than 5 seconds. Second, you can decide what data gets transmitted to the third-party server; if you use just process the form as it goes by, you will be passing along all of the post data, which is not always what you want. Same for the 307 solution, assuming it worked for all of your users.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文