I am working on a PHP application and missing some of the functionality that Rails has. I currently have an AJAX form that when submitted accesses my_page_save_ajax.php. After I process the form and save it, I would like to redirect the AJAX call to either my_page_show_ajax.php if successful or back to my_page_edit_ajax.php if an error occurred.
I have thought about using an include my_page_..._ajax.php, but I have always had problems with the file paths and PHP not knowing what to render. Not to mention, both of those files include utilities.php and I'm afraid there might be conflicts. I guess I could use include_once but it seems like there might be a more elegant solution.
How can I process the form and return the output of another PHP page?
Thanks very much!
If you redirect the AJAX response, it won't actually redirect the user's browser anywhere. It will simply affect what data comes back through the AJAX call. This may be a good instance to simply not use AJAX, since it sounds like the user may go on only one of two paths.
If you still want to redirect the user, you could send back a javascript snippet which redirects the user via setting window.location
Related
I am working on a simple PHP site that involves needing to be able to forward a request made by the user to another page (note that I said forward, and not redirect). I am aware of how to redirect by manipulating the header variable, but I do not wish to do this, as explained below.
I am trying to write a very simple MVC-patterned mailing list app in PHP, drawing from my knowledge of the same in JSP. One of the things that I appreciated about JSP was that you could both forward or redirect a request. For my purposes, I need forward as I wish to keep the request parameters (whereas redirect will drop them).
Here is a description of what I wish to accomplish:
Retrieve input from a form (ie. /add.php)
Process the input in the page called by the form's action (ie. /process.php) and add a success message to the request object
Forward to another page (ie. /display.php) to display the success message in the request object
The only way I am aware of passing the request message to display is to add it to the request object and then access it from the forwarded page. However, the only way I have had success in transitioning to another page is through using the header method, which drops the request object (from what I can tell). I want to find a way to forward the request (object) to the new page, so that I can access the request variables from the new page.
Is there actually anyway to do this in PHP? Java's getRequestDispatcher.forward() is so nice, but I can't find an equivalent through searching. I've tried several similar questions, including the following, but I've never actually found one where both the question and the answer were what I wanted. Most of the answers seem to have something to do with cURL, but I don't want to actually retrieve a file, but simply forward a request in order to access the request object from another page.
Does PHP have an equivalent of Java's getRequestDispatcher.forward()?
Let me know if I should include anything else?
I believe you can do this with include. Before submitting the form just use, as inclusion, in main page:
include ("add.php"); - where the input forms are
after processing the information, include the display.php in the same way; using this, display.php will use same parameters from header, because is included in the same main page.
briefly: add.php, process.php and display.php will be modules for the mother page, but loaded in different state of form processing.
Hope it helps!
use curl with different method get,post. it will sent a request and also get back the response.
The most common method I see of passing messages to the end user from page to page is called session flashing.
This is when you store a variable temporarily in the session until it is read.
Assuming you already have sessions in use:
On process.php:
$_SESSION['message'] = 'Your data has been saved!';
On display.php:
if (isset($_SESSION['message'])) {
echo $_SESSION['message'];
unset($_SESSION['message']);
}
You could also store the entire Request object in the session.
So if I am aware, PHP provides just basic set of tools in this case. And there is nothing like "forward" in HTTP originally. It is just frameworks' abstraction/idea. There are two ways to achieve that: copying all params from request and doing new real HTTP request (with redirect) or internal forward: so framework would create fake request and call another controller and action without issuing a new physical HTTP request.
First of all, this is my first post in Stack Overflow and I'm trying to learn PHP/MySql for a personal project that I'm working on. I think I will be spending alot of time on here to ask heaps of questions, so forgive me if I ask too many questions that you may find trivial.
On with the question.
I'm using a combination of ajax and PHP to process server side scripts. What I want to do is have a PHP module that will accept input, process something, and provide output. Much like a function.
What I'm trying to wrap my head around is how can I make PHP like a black box process module, like a function, rather than a page.
As an example, I have a login.html page which uses AJAX to send request to a login.php page. The login.php accepts the input, process the input, and output a json object which tells the calling page if it is successful, and if not will list the errors that it encountered along the way.
Here lies the issue. I don't want user to be able to go to login.php directly. In fact, I don't even want login.php to be visible to the public. The login.php is only a process, so if you go to it, it will be blank. This doesn't seem like a good practice to let users see a blank page.
I thought about putting the login.php outside the public folder, but this would mean that ajax won't be able to make a request to it either.
To get around this I have the login.html sit within the login.php. It will make a request to itself, then based on the type of request, the php will perform different things. This will resolve the "blank page" issue. But I can't help wonder if there is a way to make a standalone PHP module without having to make it work like a page also.
Any thoughts into this will be much appreciated. Thanks.
If an AJAX can request the page, then any user will be able to navigate to the page with their browser. You really shouldn't be concerned with this, because unless they snoop around they won't happen upon the PHP page. If you want a little bit of verification that the request was made by AJAX you can look for the X-Requested-With header, but this doesn't always work because every browser doesn't send this:
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
// Ajax Request
} else {
// Not AJAX, redirect to login page
header('Location: login.html');
exit();
}
To make this work reliably on every browser, you'll need to set this header on the clientside:
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
However this is still not fullproof because anyone can send a header with a program like Tamperdata, but this should be good enough to prevent the lazy snoop. Again though, allowing users to see this page (if they snoop) won't be a huge problem. It's not going to create a security vulnerability and on the off chance that a user stumbles upon the login.php page, they'll be redirected back to login.html.
Anything you send an AJAX request to can also be navigated to directly, by the nature of AJAX. All you can do is not provide the user with any indication that that page exists.
You do have the option of having one PHP file call another, via include. That way, you can have the request to login.php change behavior based on the request, but have the login handling actually processed by a file that isn't publicly accessible:
if($_POST) {include '../login-handler.php'; die();}
If a user tries to log in and the login fails the page should display an error message to the user. There are two main ways I see to do this: use a form action on the HTML page and in the php script if the login information is incorrect redirect with header to the login page with a $_GET value like loginfailed. The login page would check for this value and if it exists it would display the error.
The second way I see to do this is not use a form at all and instead use JQuery to capture the submit button press and use AJAX to determine if an error occurs. The php file would echo back a status and the javascript file would interpret it and if it was loginfailed, it would use JQuery to append the error message on to the page.
Now I will go over what I feel the pros and cons of each method are.
Method 1 Pros:
Very simplistic with no need for JQuery, Javascript, and AJAX.
The error status is displayed within the URL as well.
Method 1 Cons:
Since there is a header call, a redirect is necessary. Also, the login page must be reloaded. It is a small page but it is a reload nonetheless.
The status message is displayed in the URL. This means that users can type in status messages in to the URL and receive error messages on the page for errors that did not actually occur. Is this a problem? Maybe. Maybe not.
Method 2 Pros:
Since it is using AJAX, there is no need to load another URL and thus, no extra page is loaded.
This method uses JQuery to update the page with the error message so no redirect is necessary.
The error status is not displayed in the URL.
Method 2 Cons:
Much more complex than the first solution.
An external javascript file is needed and must be loaded every time the login page is accessed regardless of whether or not it is used.
The default behavior of the submit button is overridden and annulled. Its only behavior comes from its interaction with the javascript file.
What would SO do? I would like to stay away from answers such as "it depends on how much traffic your site would have" if that would be at all possible.
Always use the simplest solution possible until/unless there's a very good reason to do otherwise. It's better to finish something that's maybe (and maybe not) less than ideal than to deliver something gold-plated eventually, maybe.
Also, I generally prefer to follow a progressive enhancement strategy, such that everything works without Javascript, and then add Javascript to make it work in an improved manner. This has the added benefit of being functional, even when/where Javascript is disabled.
I think you fail to grasp the matter.
Login is not something self-sufficient. It is used to change state of the site. But with no reload it will not be changed. So, page reload is required anyway. or user will have to do it manually to get access to the authorized section.
Is login the only site feature that uses JQuery/AJAX? If not - why you're worrying about loading this library once, when most likely it will be loaded at every page?
There are still clients with JS disabled, for various reasons. A good web application will always let these clients in, even at cost of less functionality.
The latter is the main question, most important one. Why to choose between two? Why not to use both? - one for compatibility and another for usability?
So, I'd suggest to create basic functionality using GET to pass come codes, not messages.
And optionally improve it with some AJAX bells and whistles but with JS-based reload on succesful login anyway
Which way of redirecting from one page to other is more reliable? I need to to have a link that bring the user to blank page where some php code is executed first(in the background) and then it redirects to the target page. I would like to make this seamless, so the user is not aware that he was redirected. I used javascript for that and it worked fine, but with Javascript disabled it simply won't work. Will php redirection work in this case? Can the header() function be used after some other php code has been executed? All advice appreciated.
Redirecting from PHP with header('Location: '.$URL); die; is the most dependable redirect you can do (since it works at the HTTP level).
The only catch is that you cannot redirect this way if you have produced any output already. This is something that you can avoid by simply thinking through your code flow and designing appropriately, but if push comes to shove you can shoehorn it into an existing code base by utilizing PHP's output buffering capabilities (basic example here).
Yes, header can be called after you run php code, just be sure you don't output any text. Then send a location header.
PHP redirection will work if you didnt send any output before the header. But yes, its easy to notice that you are redirected.
yes you can execute code with PHP before a redirect. Just be certain to use the right HTTP status code for the job. (I assume the default 302 will be appropriate, but you never know.)
This method will alert the client's machine of the redirect, but tends to be seamless enough that the average user wont notice.
Why not use AJAX to call a script that processes data, and then when that AJAX is complete you can redirect to the external page?
If all your first script does is calculate data and redirect, without returning any real content, then there's not a lot of point in forcing the page to be synchronously loaded and displayed with a normal HTTP request. I assume you are allowed to use JavaScript since that's in your question.
How do I prevent my users from accessing directly pages meant for ajax calls only?
Passing a key during ajax call seems like a solution, whereas access without the key will not be processed. But it is also easy to fabricate the key, no? Curse of View Source...
p/s: Using Apache as webserver.
EDIT: To answer why, I have jQuery ui-tabs in my index.php, and inside those tabs are forms with scripts, which won't work if they're accessed directly. Why a user would want to do that, I don't know, I just figure I'd be more user friendly by preventing direct access to forms without validation scripts.
There is no way of guaranteeing that they're accessing it through AJAX. Both direct access and AJAX access come from the client, so it can easily be faked.
Why do you want to do this anyways?
If it's because the PHP code isn't very secure, make the PHP code more secure. (For example, if your AJAX passes the user id to the PHP file, write code in the PHP file to make sure that is the correct user id.)
As others have said, Ajax request can be emulated be creating the proper headers.
If you want to have a basic check to see if the request is an Ajax request you can use:
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
//Request identified as ajax request
}
However you should never base your security on this check. It will eliminate direct accesses to the page if that is what you need.
It sounds like you might be going about things the wrong way. An AJAX call is just like a standard page request, only by convention the response is not intended for display to the user.
It is, however, still a client request, and so you must be happy for the client to be able to see the response. Obfuscating access using a "key" in this way only serves to complicate things.
I'd actually say the "curse" of view source is a small weapon in the fight against security through obscurity.
So what's your reason for wanting to do this?
If the browser will call your page, either by normal request or ajax, then someone can call it manually. There really isn't a well defined difference between normal and ajax requests as far as the server-client communication goes.
Common case is to pass a header to the server that says "this request was done by ajax". If you're using Prototype, it automatically sets the http header "X-Requested-With" to "XMLHttpRequest" and also some other headers including the prototype version. (See more at http://www.prototypejs.org/api/ajax/options at "requestHeaders" )
Add: In case you're using another AJAX library you can probably add your own header. This is useful for knowing what type of request it was on the server side, and for avoiding simple cases when an ajax page would be requested in the browser. It does not protect your request from everyone because you can't.
COOKIES are not secure... try the $_SESSION. That's pretty much one of the few things that you can actually rely on cross-page that can't be spoofed. Because, of course, it essentially never leaves your control.
thanks, albeit I use
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX) {
//Request identified as ajax request
}
cheers!
Not sure about this, but possibly check for a referrer header? i think if someone manually typed in your url, it wouldn't have a referrer header, while AJAX calls do (at least in the quickly test I just did on my system).
It's a bad way of checking though. Referrer can be blank for a lot of reasons. Are you trying to stop people from using your web service as a public service or something?
After reading your edit comments, if the forms will be loaded via ajax calls, than you could check window.location to see if the url is your ajax form's url. if it is, go to the right page via document.location
This definitely isn't useful for securing something.. but I think this could be of use if you wanted to have say a php page that generated a whole page if the page was not requested by ajax but only generate the part that you needed returned when ajax was used.. This would allow you to make your site non ajax friendly so if say they click on a link and it's supposed to load a box of comments but they don't have ajax it still sends them to the page that is then generated as a whole page displaying the comments.
Pass your direct requests through index.php and your ajax requests through ajax.php and then dont let the user browse to any other source file directly - make sure that index.php and ajax.php have the appropriate logic to include the code they need.
In the javascript file that calls the script:
var url = "http://website.com/ajax.php?say=hello+world";
xmlHttp.open("GET", url, true);
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
then in the php file ajax.php:
if($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") {
header("Location: http://website.com");
die();
}
Geeks can still call the ajax.php script by forging the header but the rest of my script requires sessions so execution ends when no valid session is detected. I needed this to work in order to redirect people with expired hybridauth sessions to the main site in order to login again because they ended up being redirected to the ajax script.