Redirect in response to POST transaction

Redirect in response to POST transaction

First version, Aug 2000.
Updated Jan 2002, Oct 2004; minor tweaks at the turn of 2005-6.
Comments would still be very welcome.

Quick links to Summary and Conclusions.

Introduction

A topic that keeps coming up in various contexts is the issuing ofa redirection status in response to a POST transaction.I looked at this, quite some time back, and it was a mess.I've looked at it again, from time to time as the subject hasbeen raised in discussions, and revised the content as seemed appropriate.Management summary: it's still messy: some options work reliably,other potentially-important options only work in a subset of browsersand would would be difficult or unfeasible to deploy reliably in a WWWcontext.We also discuss some effective workarounds.

"Redirection" in this sense refers to the HTTP statusvalues 301, 302, 303 and 307, and the accompanyingLocation: header that specifies the target URL.This general topic is covered in section 10.3 of RFC2616, where it says:

This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD.

The implication is that the user agent implementation"may" (in practical terms, probably "should", althoughthe RFC doesn't say that)make some provision for actioning the redirectionspecified by the Location: header; but that there arecases where the RFC makes it a requirement to confirm with the userbefore taking the indicated action.

What's so special about POST?

The simplest situations on the WWW are "idempotent" transactions,i.e those which can be repeated without causing any harm.These are typically "GET" transactions, either because they areretrieval of straightforward URL references (e.g href=or src= attributes in HTML), or because they are formsubmissions using the GET method.Redirecting a transaction of that kind is straightforward, and noquestions asked: the client receives the redirection response,including a Location: header that specifies the newURL, and the clientreacts to it by re-issuing the transaction to the new URL.There's a difference between the different 30x status codes associatedwith these redirections in their implied cacheability, but otherwisethey are basically similar (301 and 302) in response to GET requests.

POST transactions are different, since they are defined to be, inprinciple, non-idempotent (such as ordering a pizza, casting a vote or whatever) and mustn't be arbitrarily repeated.

The HTTP protocol specifications are designed to take thisdistinction into account: the GET method is defined to beinherently idempotent, whereas the POST method is defined tobe, at least potentially, non-idempotent; the specificationscall for a number of precautions to be taken by client agents(such as browsers) for protectingusers against inadvertently (re)submitting a POST transactionwhich they had not intended, or submitting a POST into a contextwhich they would not have wanted.

Digression: more about POST

Note, sometimes the POST method is selected for an idempotenttransaction for other reasons, e.g to avoid the size limitsin implementations of GET, or to avoid the query string from being visible as part of the URL, or to getthe benefits of the multipart form encoding.These usages are not wrong, but they should not distract from the basic underlying guideline of using GET for idempotenttransactions and POST for non-idempotent ones.

A correspondent, commenting on this page, argued eloquentlyalong the lines of the previous paragraph that there ought to be a third kind of form submission,similar to POST but designed to be idempotent,and not pestering the user with the precautions againstre-submission.Whatever the attractions of this idea, we currently have justthe two, and we have to make do with what we have.

Operational view of transaction redirection

There seem to be two fundamentally different scenarios.

  1. The resource (script etc.) that handles the transaction hasn'tmoved: the "work" will be done by theoriginally-specified URL.But on completing the transaction, it wants to refer the client toa different URL, where the answer to the transaction can be viewed.(As we will see, this case isn't problematical.)

  2. The resource (script etc.) that is supposed to handle thetransaction (that "does the work", to put it crudely)has moved. The addressed URL invites the client tore-present the transaction to the new URL, where the "work" willactually be done.(As we will see, this has been poorly supported, and is stilllikely to be problematical in a WWW context:some other approach is needed.)

These distinct behaviours are not directly associated with one orother of the 30x status codes, they depend also on the details ofwhat the scripts at the two URLs actually do with the requests.But the idempotence principle implies some restrictionson how they should properly be used.

To be explicit: a POST transaction that has been redirected to a GET transaction with the intention of carrying out the "work" at the new URL, would only be acceptable if the"work" was idempotent, by virtue of the operative transactionbeing a GET. A non-idempotent transaction ought not to be handledin this way.

On the other hand if the "work" is carried out at thefirst URL, and the only purpose of the redirection is to direct theclient to a URL where they can view the answer (this might be a prepared standard thank-you page, or one of a selection of preparedstatic success/failure page(s) for example), then the fact that theredirection results in a GET transaction is quite appropriate:indeed a static page cannot accept a POST request.

The situation with status 302 from HTTP/1.0 was unsatisfactory, as we discuss shortly.HTTP/1.1 amended the definition of 302, and introduced two separate statuses, 303 and 307,with the intention of clarifying the behaviour.

Aside

There's a scenario that comes up in Usenet discussions,where people are trying to invoke pre-packaged CGI scripts: theyactually want to invoke two different prepared scripts in successionas part of the same POST transaction. As we will see in the subsequentdiscussion, this is not really practical in the form in which it'sposed, and would be better addressed by a different approach.

One possibility would be to write a small "glue" routine whichhandles the CGI transaction by invoking the two prepared scripts in succession, retrieves their responses, and constructsan appropriate overall CGI response for the whole activity.OK if both scripts are on the same server.If the scripts are on different servers, then one server can beset up to handle the transaction from the client, andto remotely invoke the transaction(s) on remote server(s) behind thescenes, before returning the result to the client. In this way the client is shielded from any details of the mechanism, and isn't required to support POST redirections in order to make it work.Details of how to do this are beyond the scope of this note(Apache can be configured to "proxy" such requests, for example).

An email correspondent contacted me about this point, with aproposal in which he wanted to use the firstsuch script to validate the submitted form parameters, and then,after redirection with status 307, the second script was intended to action the transaction. I found this quite alarming -I had to point out that the client agent (and thus,the user, if they so choose) would get control of the submissionparameters after they had been validated by the first script, andcould mischievously change them before submitting them foraction at the second script.I would rate it as essential to avoid any contact with the user at such a sensitive point in the proceedings!

Review of the specifications

The reader should of course make themselves familiar with the relevantpart of the HTTP/1.1 specification; here I am only attemptingto look at the requirements of thespecification and see how they relate to possible applications andsolutions in a WWW context.

Historically, in HTTP/1.0, status 302 (temporary relocation)was documented to call for the response that is now,in HTTP/1.1, documented for status 307.However, the popular browsers did not implement that specification: instead, they implemented theresponse that is now documented for status 303.Lynx in the distant past implemented the original specification forstatus 302, but later it was brought into line with the de-facto behaviour of other browsers.

HTTP/1.1 now codifies the de facto behaviour in responseto status 302, but it documents two separate status codes, 303 and307, for resolving the ambiguity.

Where there seems reason to suppose that the redirection willcause a non-idempotent transaction to be performed in a differentcontext than the original submission implied, the HTTP specificationforbids the client to silently perform the redirected transaction -instead the client must first get the user's confirmation to proceed:in relation to requests submitted with the POST method, thisobviously applies to statuses 301 and 307, but also (perhapssurprisingly) to status 302.User verification isn't necessary for status 303, as should beclear from the previous discussion.

As we will see, the mandate in regard of status 302 is widelydisregarded, and, since de facto 302 is practically always nowtreated in the way that is specified for 303, the likelihood oftaking some irrevocable action that had not been intended seemsto be quite small.

As for status 301, the HTTP/1.1 specification re-iterates therequirements that were already in HTTP/1.0: when redirectinga POST request it mandates clients to verify the redirection withthe user, and describes the behaviour of "some existing useragents" in converting the POST into a GET as "erroneous"(for all the good that might do...).

A correspondent writes that some of the statements whichI make about specified client agent behaviour in response to 3xxare not stated in so many words in RFC2616.However, if we take the statuses one by one, I think it'sreasonably clear: for status 301 it rates a redirection of POST to GET as "erroneous"; for 302 and 303 it documents that redirection of POST to GET is now considered to be correct; and it refers back to therequirement in RFCs 1945 and 2068 that the client was "not allowed"to change the method on the redirected request.Therefore, it seems that the only reasonable interpretation isthat unless otherwise stated (i.e for 302 and 303), the properway to perform redirection is by repeating the original "method",i.e for our present context, POST shall be redirected to POST.

See also Common User Agent Problems,specifically 3.4 about temp redirects,and 4.1 Handling the fragment identifier.

A point of dispute? - mandatory confirmation of 307

An email correspondent writes to complain bitterly about theRFC2616 mandatory requirement to confirm status 307 with the user,which in practice is honoured by the web-compatible browsers which implement such redirection; and praising MSIE for disregarding themandatory requirement.

As this correspondent said, most users are in no position to answer the question whether they had intended their submission to be redirected in this way, and have no basis on which to decide.True enough, if they haven't been briefed beforehand about what toexpect; but presumably the authors of RFC2616 had in mind the possibilities for abuse when a non-idempotent transaction is silently redirected to somewhere else.I could only advise my correspondent that, the way things currently are, their best move was to redesign their procedureso that it was not reliant on status 307.(And also not reliant on MSIE violating a mandatory requirement of RFC2616, considering that IE has recently beentightened-up on this or that earlier disregard of web specifications.)

Implications for cacheing

There are two aspects of cacheing involved:

  1. The cacheability of the redirection response itself,

  2. The cacheability of the resulting document, that will be returned after the redirection has been actioned.

These two issues are quite separate from each other,and should not be confused.To take a practical example: where a transaction will result inone of a small number of static responses, it can make good senseto return the result by redirecting (non-cacheably) to the appropriate (cacheable) static document.

Status 301 redirection response is inherently cacheable:a client receiving this redirection response couldstore the fact that the first URL was permanently redirected tothe second URL, and any future request specifying the first URL couldbe presented immediately to the second URL, without invoking thefirst URL and waiting to be redirected.This behaviour is permitted, but not mandated, for status 301.

Status 303 redirection response is forbidden to be cached.

Status 307 redirection response is by default notcacheable, but it is eligible to be cached if the response containsappropriate headers to that effect.

As for the documents that are returned after a redirection responsehas been received, they are at least eligible to be cacheable.Under the various 30x response codes, RFC2616 contains some remarksrelevant to this issue.

The Query String

To address some misunderstandings that have occurred about thequery string when a POST transaction is redirected as a GET: the client does not automaticallyaffix the original POSTed parameters to the query string partof the new URL when actioning the redirection.If the intention was to supply the original query onto theGET transaction to the new URL, then it would be the job of thescript that is creating the redirection, to obtain the submitted parametersfrom the initial POST transaction, and to include them,properly formatted, as the query part ofthe new URL (on the Location header) to which the redirection is being specified.(Sure: transferring the parameters from a POST to a GET transaction could very well defeat one or other of thereasons that led to POST being chosen in preference to GET in thefirst place - I'm only exploring the issues at this point, notmaking a design recommendation.)

Fallback behaviour

The RFC provides for redirection transactions to be accompanied by a "short hypertext note with ahyperlink to the new URI(s)", which is intended to beused by clients that do not implement the particular redirectiontransaction automatically.

However, it should be obvious that such a "hyperlink" isn'tdirectly useful if the redirected transaction is intended tobe presented by the POST method, since a href=presents a GET transaction.If this fallback document was to be of any use for that purpose,it would need to contain a fresh HTML form element,specifying the new URL as its action, and (presumably) containingthe parameters of the original transaction as hidden fields.(This is not an original idea - after I hadrealised that it was a possible solution, I found that it had alreadybeen proposed by Klaus Weide in 1997.)If such a procedure was attempted at all, then it would have tobe handled very carefully by the designer: the parameter values wouldneed to be re-validated to avoid the possibility that they had beeninterfered with by mischievous users before resubmission.On an operational note, users who were presented with this kind ofscenario in an otherwise critical situation (e.g shopping) mightwell get cold feet and bale out of the whole procedure.

Description of Test Procedure

The tests start with an HTML form, whose form tagspecifies POST submission to the first CGI script. How this formis generated is unimportant as far as the tests are concerned:it could perfectly well be a static HTML page.

One of the parameters that is submitted with the form is an indicator of which kind of 30x response is desired (the testerselects this from an options list prior to submitting the form).

The form is then submitted (by POST to the first CGI script).

The CGI script, which is coded in Perl, responds by generating the redirection response.In order to have clear control over the exact CGI response headers generated (unlike the rest of the scripting which uses CGI.pm), thispart of the procedure uses straightforward printstatements to print the desired headers (and body content) to thestandard output (something I normally would avoid, thanks to thesimplicity of using CGI.pm).However, the scripts are normal Parsed Headers scripts,they are not NPH (non-parsed headers) scripts.There didn't seem any reason to suspect that the resultingHTTP stream generated by the server (Apache 1.3.*) was in anyway defective such that an NPH script could achieve better results:anyway, parsed-headers scripts are probably more realisticin terms of normal WWW applications and thus the test seemedentirely reasonable in this form.

The redirection response (at the CGI interface) that isgenerated by the first script consists ofthe Status: CGI header specifying the desired30x status and reason text (the server of course turns this intoan actual HTTP response for transmission to the client), thenthe Location: header specifying the URL of thesecond script. Then comes the fallback provision, consisting of aContent-type: text/html header, separated from thefallback HTML document by the usual blank line that separatesthe CGI header part of the response from the response body.For diagnostic purposes, the HTML response body includesprintouts of the query parameters (CGI::dump() method) andthe CGI environment.In the fallback situation, the client would be expected todisplay this document, showing the environment etc. as itwas seen by the first script.

Finally we describe the second CGI, to which the client willbe redirected and which, in the event of the client honouringthe redirection rather than displaying the fallback document,will be returning the final display.This too is a diagnostic script which displays the CGI environment (i.e as it was presented to thesecond CGI script).This script additionally dumps the POST transaction's queryname/value pairs, so as to verify correct redirection of POST transactions.

No intensive effort was put into investigating whether the variouscacheability rules were being honoured.The server log was inspected to verify that the expected transactionswere being fielded by the server rather than the client redisplayingcached results, but beyond that the details were not investigated.

It could very reasonably be argued that in my tests, Ishould not have tested the response of HTTP/1.0-type clientsto status 303 and 307, since those are not part of HTTP/1.0.Nevertheless, I did so and report the results.But I can assure you that this doesn't affect the conclusionsreached: as we will see,whichever way the results are interpreted, there is no reliableway, in the WWW context, of getting a POST transaction at the first URL redirected to a POST transaction at the second URL.

Extra caveat: some proxies will modify an HTTP/1.1 clientrequest into an HTTP/1.0 request.However, it didn't appear that this effect was causing any significantdifference in client/server behaviour, whether the client was workingthrough such a proxy or not.

Test results in detail

According to the specification, clients don't necessarily haveto make any provision for followingthe redirection specified in the server's Locationheader: but if they do make such provision, then theyneed to conform to the requirements of the RFC.The key requirements, for POST requests, seem to be these three:

  • Whether a user confirmation is required,
  • Whether the POST transaction is redirected to POST or to GET,
  • The cacheability of the redirection itself.

The present page concentrates on the first twoof those issues; the third was not studied in any detail.Discussions at the Mozilla Bugzilla also consider what the browser'sbehaviour should be with regard to which URL (before or after redirection) topresent to the user (e.g in the URL field), and which URL (before orafter) to bookmark if the user attempts a bookmark (although I mightremark that bookmarking the result of a POST transaction might notbe particularly useful in practice, and is quite unlikely to produce the result that the user had hoped for).These issues are not explored further in the present page.

The notes below summarise what those requirements are.The order in which the tests are listed was chosen for convenienceof back-references.

303 See other

What the specification wants:
The client should present a GET request to the new URLspecified in the Location: header.No user confirmation is required.
Win IE5, 5.5, 6
Correct behaviour observed
Netscape 4.7 Win32
No redirection performed. Browser displays the fallbackpage instead
Opera 6.04, also 7.23
Correct behaviour observed
Mozilla 1.3.1 Win32, also 1.6
Correct behaviour observed
Lynx 2.8.3
Correct behaviour observed

302 Found

What RFC2616 wants:
As for 303, except that RFC2616mandates verifying the redirection with the user.(This differs from the HTTP/1.0 specification for 302, whichwas widely ignored by browser developers.)In practice, the mandatory verification is widely disregarded:as the earlier discussion shows, in practical terms this widespread technical defect can probably be rated as being of low significance.
Win IE5, 5.5, 6
Redirection performed but without the mandatory verification
Netscape 4.7 Win32
Redirection performed but without the mandatory verification
Opera Win 6.04, also 7.23
Redirection performed but without the mandatory verification
Mozilla 1.3.1 Win32, also 1.6
Redirection performed but without the mandatory verification
Lynx 2.8.3
Redirection performed but without the mandatory verification

307 Temporary redirect

What RFC2616 wants:
Client is to re-present the POST transaction to the new URLafter verifying the redirection with the user.
Win IE5, 5.5, 6
Redirection to POST performed, but without the mandatory verification (this has to be ratedas a severe bug in the terms of the HTTP specification)
Netscape 4.7 Win32
Redirection not performed.Fallback page presented instead (permissible behaviour).
Opera Win 6.04, also 7.23
Correct behaviour observed: browser presented a user dialog in whichthe default action was to redirect to POST.
Mozilla 1.3.1 Win32
Redirection performed as for 303 i.e completely wrong.
Mozilla 1.6 Win32
Correct behaviour!
Lynx 2.8.3
Correct behaviour

301 Moved permanently

What the specification wants:
As for 307, except that the client may(not "must"!) retain the redirection and apply it automatically to futurereferences to the redirected URL.RFC2616 explicitly cautions that some existing clientswill redirect to a GET transaction and that this is erroneous:guess which browsers they are referring to?
Win IE5, 5.5, 6
Erroneous: Redirects the transaction to a GETwithout the mandatory verification with the user: bothof these are wrong according to the spec.As far as I can see, the browser is not treating thisredirection as permanent: subsequent references to the firstURL are still presented to the first URL for redirection(either behaviour is permissible according to the spec.).
Netscape 4.7 Win32
Erroneous:this too redirects the transaction to a GETwithout the mandatory verification with the user.
Opera Win 6.04
Correct behaviour observed: browser presented a user dialog in whichthe default action was to redirect to POST.
Opera Win 7.23
Erroneous:this version has reverted to the incorrect behaviourthat is criticised in RFC2616, so that now itbehaves like the other popular browsers.
Mozilla 1.3.1 Win32, also 1.6
Erroneous:redirection performed as for 303 i.e like MSIE and NN4 completely wrong.
Lynx 2.8.3
Displays a warning that permanent redirection is handledas temporary; then proceeds as for 307. (Acceptable behaviouraccording to the specification).

On several contentious points, Opera has a reputation of doing what seems to be in the short-term interest of its users, no matter what the specifications might require. And we see an example of this behaviour here, in that the specification-correct behaviour of Opera 6.* had been brokenin 7.* to conform with the broken behaviour of the mass browsers.That's understandable in a commercial product, but unfortunatelyit also reinforces the defective behaviour to which it's attemptingto accommodate.Arguably it (or any other browser offering this kind ofstrategy) should throw an ostentatious warning, before accepting its user's consent to proceed inany way that's contrary to the applicable specification.

This paragraph is just "thinking aloud", and not really part of the present tests.It's at least arguable that the attempt by HTTP/1.1 to specifybehaviour for status 301 has proven to be a failure, just as the attempt by HTTP/1.0 to specify behaviour for status 302 failed before.By analogy, one possible way out would be to introduce a pairof new status values to replace 301, one of which would require theclient agent to behave as 301 was specified to behave, i.e a cacheable counterpart to 307, andthe other of which would behave in the way that 301 has beentypically implemented, i.e a cacheable counterpart to 303.However, considering the dilatory implementations of status 307, it's hard to take this as something worth losing any sleep over.The "long and short" of it, as far as a web developer is concerned,is that status 301 in response to POST is practically useless,since a cacheable redirection of a POST transaction to a GET URLdoesn't seem to be the kind of thing one would really need, even ifone could rely on all browsers implementing it in that anti-RFC2616 way.whereas when there is a genuine requirement for POSTto be redirected permanently to POST, there is no way of implementingit reliably with status 301, although (if you trust browsers toimplement 307, which they haven't been particularly good at), youcan get something broadly similar by using status 307 together withappropriate cacheability headers.

Comment on MSIE

An email correspondent calls my attention to an MS Knowledgebasearticle, KB179611, which documents an "advanced" option which, ifenabled, will cause all redirections to be verified with the user.My correspondent commented that he had tried it, and it seemed tohave no effect.Well, now that I have tried it myself (Win IE6 6.0.2800.1106 witha bushel of security fixes applied), I have to report that it seemedto have no effect for me, either.Indeed the KB article lists the products to which it applies, andthe newest browser version listed is IE5.0, so if that's true (ratherthan merely being out of date), it seems as if they've dropped thefeature, despite there still being a checkbox for it in the advanced options.

Suffice it to say that this option would have been at itsdefault setting in my tests which are reported here.

Other browsers in brief

Netscape Gold 3.01 (mis)behaved pretty much the same as Netscape 4.7.

Mozilla 0.9.7: statuses 301 and 307 were wrongly redirected to GET.This is Bug48202, which was still present in Mozilla 1.3.1.

The next version of Mozilla on which I reviewed this issue was 1.6, and now it seems that status 307 is behaving correctly.However, the behaviour of status 301 seems to be unchanged.The bug chain is confused: bug 48202 is titled for status 307, butit goes on to also discuss 301. What has been fixed is the behaviourfor status 307, and the bug has now been marked as fixed. But meantime, the bug entry 69376references 81636which is asking for the (incorrect, although it doesn't say so)response to status 301 to be cached.However, this has been marked as a duplicate of bug 48202,despite the fact that 48202 has now been marked fixed withoutapparently addressing either of the issues (the correct response, northe cacheability).

By the way, Mozilla bug 68423is also somewhat related, but on closer inspection, does not impactdirectly on the issues discussed here.

Opera (4.10 pre-release) redirected 303 and 302 to GET,and 307 and 301 to POST, all withoutuser verification.

Opera 6.0 (release) behaved correctly, aside from the lack ofa user dialog for status 302. Statuses 301 and 307 produced identicaluser dialogs, by which the user was invited to consent to the POSTtransaction to the new URL (this was the default response), alternatively to GET the new URL or to cancel the transaction.6.04, as seen above, is the same.

WebTV Viewer 1.1: treated all four statuses as specified for303 (no verification with user, redirected as GET) while displayingthe status message "Relocation in response to POST".

Win MSIE 3.03 16bit also treated all four statuses as specifiedfor 303.

As did w3m(990901). As did iCab 2.1pre.

Test results summary

BrowserStatus codes
303302307301
Win IE5, 5.5, 6OKOK*OK*Wrong
Mozilla 0.9.7 ... 1.3.1OKOK*WrongWrong
Mozilla 1.6OKOK*OKWrong
Opera 6.0, 6.04OKOK*OKOK
Opera 7.23OKOK*OKWrong
Netscape (Win 4.7, 3.01)FallbackOK*FallbackWrong
Lynx 2.8.3OKOK*OKOK
WinIE3, WebTV, w3mOKOK*WrongWrong

In the table:
OK = within the HTTP/1.1 specification,
OK* = ditto, except missing the mandatory verification with the user,
Wrong = erroneous behaviour,
Fallback = displays the fallback page.

Conclusions

Automatic redirection of a POST transaction to GETis entirely feasible, using status 302 or 303.Although the specification for 302 mandates clients to verify the redirectionwith the user, this mandate seems to be generally ignored, butthat can be rated mostly harmless, as previous discussion showed.

In a usenet discussion, Kevin McMurtrie commented that 303 isonly specified in HTTP/1.1, so he would test the HTTP level(SERVER_PROTOCOL) in the script, and respond with 302 for HTTP/1.0 and 303 for HTTP/1.1:this does indeed seem to be a good idea in theory, and I don't knowany practical reason against it, so that would now be my recommendationtoo.

In either case it's a good idea to supply a short HTML content bodywith an appropriate link, and an explanation of the situation for thebenefit of any browsers which fail to follow the redirection.

Redirection of a POST transaction to another URLas POST evidently works only in a subset of browsers(namely, modern versions of the popular browsers, and a subset ofminority browsers), making its use in a WWW context unreliable:this is true for status 307, and even more so for status 301.Testing the protocol for HTTP/1.0 or HTTP/1.1 doesn't resolve thisissue, because it wasn't only HTTP/1.0 clients which misbehaved.Trying to rely on fallback behaviour is not a viable strategy, sinceseveral browsers take the wrong actionrather than taking the fallback.

It would seem to need considerable ingenuity to cope with the variousbrowser responses in a reliable way, and (except in non-WWW situationswhere the browser population is under control) I would have to recommend finding some other approach for achieving the desired result, in general.Even in those browsers which correctly implement the protocol, theuser would be presented with a disturbing prompt from their browser,which might lead them to believe that all was not well and toabandon the activity at that point, which is another reason foravoiding this if you possibly can (except perhaps with a well-controlled and well-briefed group of users).If the whole server-side process cannot be re-cast to avoid theissue entirely, then the solution might involve proxy-ing some partof the transaction on the server, and merging the result into theresponse on the server side, so that the client side is unawareof the "seams".

One clumsy option in a WWW context to mimic theintended result would be to have the first script construct anew form with the desired POST transaction prepared, andto send it back as a normal page, with the user invited to resubmit it.Whether this could be an acceptable solution in any particular caseis left as an exercise for the reader.

I think, in fairness, anyone who is wanting to do thatwould be better advised to look towards theproxying or relaying approach as already mentioned(and there's one practical suggestion offered below, but goinginto the various options in detail would take us beyond the scope of this web page).

Addendum

An email correspondent reports successfully using Perlin the first CGI script, to submit the POST request"behind the scenes" to the URL of the second CGI script, capture the response, and return it to the client.This snippet of Perl does the trick, I'm told:

Using the LWP::UserAgent module, I created a new user agent and createda new request header based on the content posted to the script.

  my $req = new HTTP::Request ('POST',$thisUrl,$h);
  $req->content_type('application/x-www-form-urlencoded');
  $req->content("myData=$someData");

# Pass request to the user agent and get a response back
  my $res = $ua->request($req);

# Check the outcome of the response
  if ($res->is_success) {
    print $query->header(-target=>'_blank');
    print $res->content;
    exit(0);
  }

The only caveat is that content in the response is resolved locally, andso all of the URLs on the requested page need to be absolute.

As always, this is a best-efforts production andno liability can be accepted.Corrections would be most welcome.


| Up |  | RagBag | About the author |



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值