I'm trying to do a header redirect in PHP doing something like:
header("Location: http://www.domain.com/some/url");
exit;
This works fine when making a GET and POST request however it doesn't seem to work with PUT and DELETE requests.
I've tried doing:
header("Location: DELETE/PUT http://www.domain.com/some/url");
exit;
But that doesn't seem to work, also calling the url directly works fine. I can echo some text before and after the header call, so everything is working, seems to just ignore PUT and DELETE requests?
Similar question, possible same answer applies to you
The header function is used to send HTTP response headers back to the
user (i.e. you cannot use it to create request headers.
May I ask why are you doing this? Why simulate a POST request when you
can just right there and then act on the data someway? I'm assuming of
course script.php resides on your server.
To create a POST request, open a up a TCP connection to the host using
fsockopen(), then use fwrite() on the handler returned from
fsockopen() with the same values you used in the header functions in
the OP. Alternatively, you can use cURL.
PS: I see that it is also displayed under Linked tab :)
Using Location is not the proper way to set the HTTP Method header.
Try the following:
header("Request-Type: DELETE");
header("Location: http://www.domain.com/some/url");
exit;
However, I am not sure you can set request types with header() alone. I know you can with cURL.
Related
when use GET Method for receive JSON data , we can acsses the result directly from web browser , for example i send a mydata value from ajax to a main.php file and it process and get answer show a result some thing like below :
<?php
if (isset($_GET["mydata"])) {
if ($_GET["mydata"]=="hello"){
echo "hello world";
}
}
?>
but when a user call it in browser directly like http:mysite.com/mydata.php?mydata=hello recive answer . i want dont allow users to get answer of http request directly , and just can show it from ajax result of main page is it possible ?
You're asking how to prevent an ajax-only request from being accessed directly by copy-pasting the URL into the web browser; that is, only allowing the URL to be accessible via ajax on the main web page.
Well, there are a few things you can try:
Check the Referrer for the URL of the main page with $_SERVER['HTTP_REFERER']
Set a header in Javascript using xhr.setRequestHeader() and then ensure it's value by checking for $_SERVER['HTTP_X_....'] in PHP
Like Jay Bhatt recommended, check for the X_REQUESTED_WITH header, but be aware this might not always be set (see: X-Requested-With header not set in jquery ajaxForm plugin)
However, in any of these situations you should be aware that anyone who knows what they are doing can easily set any HTTP header, variable, or even modify the referrer which is sent to the server. As such, there is no 100% guarantee that your resouce can be accessed only via AJAX on the main web page. There is no control built in the internet to verify where a request is coming from, so anyone can easily spoof or fake it.
I need to redirect users if I don't want them to be able to access a certain page. How reliable is header('Location: ../acc/login.php'); for example? Can browsers ignore 302 errors, and is this the right way? Thanks in advance!
It depends a lot what you're trying to do. Technically spoken, header() is somewhat reliable. Only somewhat, because many PHP users have problems with it and to not get it to work.
PHP will prevent it from working if output has been already send to the browser. A drastic example:
<protected page content here>
<?php
header('Location: login-first.php');
exit();
?>
This would not work at all. You would eventually see even an error message with a warning.
Headers - by design - need to be send out before any other content (response body). They can not be send any longer if the response body has already started and PHP can't help you then in that case.
However, if you send headers before the response body, that function will work. Also the risk obviously to mess something up is not that drastic any longer, too:
<?php
header('Location: login-first.php');
exit();
?>
<protected page content here>
You can rely on header(), but make sure you called die(), exit() or return after that. Otherwise, script will continue its execution, which is potential security issue.
The browser can ignore header('Location: '); forwarding.
That is why you should always return after a call to a header() forward so the rest of your code does not execute should the browser not honor the forwarding.
It is the correct way to do things tho.
I would send the header command and then the exit command "exit()" (to stop running the php code on the server) before displaying the rest of the page. This way the user would never be sent the page content even if they ignored the 302 redirection.
And yes the user can ignore the 302 redirection:
http://www.webmasterworld.com/html/3604591.htm
header is 100% reliable.
However header('Location: ../acc/login.php') will be evaluated in the browser to a real location on your website, and ../acc/login.php wil not form a url that is valid!
I am working with an API for a payment gateway that does a callback request.
When the callback request is made, the gateway expects me to respond with "OK".
Nothing more or less. And that doesn't mean html rendered response. Just a callback file with those 2 letters. Note that doesn't mean it wants HTTP Status Code 200/OK... it wants actual data (not headers) for the word "OK".
So this won't work:
<html><body>OK</body></html>
This will work:
<?php echo "OK"; ?>
however, after I send back OK, I need to do some stuff on the server side and then redirect the browser page to another page. But when I try to do:
<?php
echo "OK";
header('Location: http://www.store.com/success.php');
exit;
?>
The gateway ignores the echo "OK" and instead reads the html off of the success.php page that I redirect to.
So how can I send back just the OK but continue doing things on my side?
Thanks
You can't send content then redirect. The redirect header setting must be done alone.
You could try using flush(); to force php to write out the OK.
Would it be acceptable to move the redirect into client side either with javascript or meta refresh tag?
Before you send the OK you could call PHP via commandline to make PHP acting like multi threated.
So I know the general rule of thumb is after doing a header redirect in PHP, you should call exit() to avoid having extra code running, but I want to know if you put code after the redirect header, if it will always run?
I was doing some research on various ways of tracking referrals in Google Analytics and came across this post: Google Analytics Tips & Tricks – Tracking 301 Redirects in Google Analytics
It recommends doing something like this:
<?
Header( “HTTP/1.1 301 Moved Permanently” );
Header( “Location: http://www.new-url.com” );
?>
<script type=”text/javascript”>
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
</script>
<script type=”text/javascript”>
try {
var pageTracker = _gat._getTracker(“UA-YOURPROFILE-ID”);
pageTracker._trackPageview();
} catch(err) {}</script>
From the way I've always understood the header() function, it's up to the browser and it can run the redirect whenever it wants to. So there's no guarantee the JavaScript would actually begin or finish executing prior to the redirect occurring.
PHP's documentation for the header() function indicates the reason for exiting after a redirect is to "make sure that code below does not get executed when we redirect." That doesn't sound like they guarantee all following code will run, just that it could happen.
Regardless, I found a different way to actually manage the tracking, but I wanted to see if I could find out how exactly header() worked in this situation..
Thanks for your help.
Using the header function in PHP only adds to the headers of the response returned by the server. It does not immediately send any data and does not immediately terminate the connection. Any code after the header call will be executed.
In particular, it's a good idea to add a response body even after doing a 301 redirect so that clients that do not support the redirect also get some descriptive response. Infact according to the HTTP 1.1 specification Section 10.3.2 -
Unless the request method was HEAD, the entity of the response SHOULD
contain a short hypertext note with a hyperlink to the new URI(s). If
the 301 status code is received in response to a request other than
GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
It's a race condition. Once the redirect header is sent to the browser, the browser will close the current connection and open a new one for the redirect URL. Until that original connection is closed and Apache shuts down the script, your code will continue to execute as before.
In theory, if there was a sufficiently fast connection between the client/server, and there was no buffering anywhere in the pipeline, issuing the header would cause the script to be terminated immediately. In reality, it can be anywhere between "now" and "never" for the shutdown to be initiated.
The HTML after your Location line doesn't run inside PHP; it would run in the browser. It's up to the browser whether or not to execute the Javascript that you've included on that page; PHP has nothing to do with it.
To me, the PHP docs imply that any PHP below the header() when you send a redirect will continue to run. But it 'runs' in the PHP interpreter, dumping JS to the browser. There's no relation between what it says in the PHP docs and whether or not the JS gets run by the browser.
EDIT:
Well, as Anupam Jain pointed out, looks like that browsers do not terminate connection without getting the response body and it sounds sensible. So i rethinked my answer
That doesn't sound like they guarantee all following code will run
Exactly More likely it's a warning in case there is some sensible code that shouldn't be executed. A private page contents for example. So, beside sending header you have to also make sure that no sensitive content were sent and exit looks like quite robust solution. So, I'd phrase it as "make sure that sensible code below does not get executed when we redirect."
So there's no guarantee the JavaScript would actually begin or finish executing prior to the redirect occurring.
Exactly It seems it has nothing to do with script execution but rather with browser's will to execute anything after getting 3xx response. I think I'm gonna test it, but you can test it as well too.
I have noticed that the code does still execute and multiple headers based on if statements can cause a "redirect loop error". i made it a habit to now add in die("Redirecting..."); after every header redirect and have not see the problem persist.
In my test.php file, I sent a request to a Flickr app I have using
header("Location: " . $request);
where $request is the URL that I am trying to reach on Flickr.
For my Flickr app, I have to set a callback URL. When Flickr is done with processing my request, it will call the callback URL.
I would like the callback URL to be my original page, test.php. When I try this, I get stuck in an infinite loop, because test.php is re-sending the request back to Flickr, and Flickr calls my test.php again (repeat ad infinitum until the browser quits).
Is there a way to put some kind of conditional in test.php to check if the request came from Flickr, or at least some way to let the script know that the request has been sent, so don't send it again.
I've already tried it where I changed the callback URL to another page of mine, and that works fine. I'm just seeing if I could re-use the same page.
Its ugly.
The two posted solutions won't work because:
The referer isnt changed on redirect (well it is cleared if its a http meta redirect, but not if its a header redirect. but it doesnt become something else so easy).
Putting exiting after a sent header is generally a good idea if there is something else normaly executed afterwards, but its not related to the problem.
Simply put, if it should be the SAME page, you need to to store in a file or database or something the redirect counts per ip adress/user and break or something but NONE of this is really reliable. You can make it more secure by having a secured token that cannot be reverse engeneered etc but all this doesn't make sense. You could also use cookies. Which is just as unreliable as well.
Regarding your problem, flickr does NOT redirect back to the samep age.
Regarding to their specifications they append ?frob=[frob].
http://www.flickr.com/services/api/auth.spec.html
Check for that:
<?php
if(!isset($_GET["frob"])) {
header("Location: " . $request);
exit();
}
?>
try checking the referer with the $_server['HTTP_REFERER']
[Edited]
I just wanted to say that, you should try adding if condition
// just and example, use some regular expression to check the refere
if($_SERVER['HTTP_REFERER'] != http://flicker.com){
header("Location: " . $request);
}else{
// another code
}
Thanks
As an alternative to checking for the (non-)existence of $_GET["frob"], couldn't you set the callback url in Flickr to be www.mysite.com/test.php?from_flickr=1 and then do
if (!$_GET['from_flickr']) {
header('Location: '.$request);
exit;
}