This is a newbie question to AJAX experts: In case an unauthenticated user tries to post a comment to an article and send it to the server through AJAX, I need the remote PHP script to return...
a 401 and a logon/password form which the user will fill and try again, or
a 301 to redirect the user to a full-page logon/password form which, if successfull, will then return the user to the original comment page.
If possible, I'd rather use AJAX for both authentication + posting, so that the user doesn't need to see a full page just for authentication. Is it possible? FWIW, I'm using jQuery to learn about AJAX.
Thank you.
Yes. Your AJAX script might be making a request to, say, comment.php. That script should check if the session has been authorised, usually a variable in $_SESSION['...']. If so, then the comment should be handled. If not, the user should be directed by that script to log in.
Related
I am having a very hard time understanding the exact process of "post/redirect/get".
I have combed through this site and the web for several hours and cannot find anything other than "here's the concept".
How to understand the post/redirect/get pattern?
Wikipedia explains this so well!
The Problem
The Solution
As you may know from your research, POST-redirect-GET looks like this:
The client gets a page with a form.
The form POSTs to the server.
The server performs the action, and then redirects to another page.
The client follows the redirect.
For example, say we have this structure of the website:
/posts (shows a list of posts and a link to "add post")
/<id> (view a particular post)
/create (if requested with the GET method, returns a form posting to itself; if it's a POST request, creates the post and redirects to the /<id> endpoint)
/posts itself isn't really relevant to this particular pattern, so I'll leave it out.
/posts/<id> might be implemented like this:
Find the post with that ID in the database.
Render a template with the content of that post.
/posts/create might be implemented like this:
If the request is a GET request:
Show an empty form with the target set to itself and the method set to POST.
If the request is a POST request:
Validate the fields.
If there are invalid fields, show the form again with errors indicated.
Otherwise, if all fields are valid:
Add the post to the database.
Redirect to /posts/<id> (where <id> is returned from the call to the database)
I'll try explaining it. Maybe the different perspective does the trick for you.
With PRG the browser ends up making two requests. The first request is a POST request and is typically used to modify data. The server responds with a Location header in the response and no HTML in the body. This causes the browser to be redirected to a new URL. The browser then makes a GET request to the new URL which responds with HTML content which the browser renders.
I'll try to explain why PRG should be used. The GET method is never supposed to modify data. When a user clicks a link the browser or proxy server may return a cached response and not send the request to the server; this means the data wasn't modified when you wanted it to be modified. Also, a POST request shouldn't be used to return data because if the user wants to just get a fresh copy of the data they're forced to re-execute the request which will make the server modify the data again. This is why the browser will give you that vague dialog asking you if you are sure you want to re-send the request and possibly modify data a second time or send an e-mail a second time.
PRG is a combination of POST and GET that uses each for what they are intended to be used for.
Just so people can see a code example (this is using express):
app.post('/data', function(req, res) {
data = req.body; //do stuff with data
res.redirect('public/db.html');
});
So to clarify, it instantly refreshes the webpage and so on refresh of that webpage (e.g. if you updated an element on it) it won't repost the form data.
My code used to look like this:
app.post('/data', function(req, res) {
data = req.body;
res.sendFile('public/db.html');
});
So here the response is sending the html file at the /data address. So in the address bar, after pressing the submit button it would say for me: localhost:8080/data.
But this means that on refresh of that page, if you have just submitted the form, it will submit it again. And you don't want the same form submitted twice in your database. So redirecting it to the webpage (res.redirect) instead of sending the file (res.sendFile) , stops the resubmission of that form.
It is all a matter of concept, there is no much more to understand :
POST is for the client to send data to the server
GET is for the client to request data from the server
So, conceptually, there is no sense for the server to answer with a resource data on a POST request, that's why there is a redirection to the (usually) same resource that has been created/updated. So, if POST is successful, the server opiniates that the client would want to fetch the fresh data, thus informing it to make a GET on it.
I have a form in my html which has an action url to different domain. After submit, it redirects the browser. I want it to be submitted but not redirected to another page. I know i can submit it with Ajax but since the domain is different it gives CORS error. I cannot mirror request in my own php file because form submission is made by virtual credit card payment system and it doesn't allow you to mirror it.
So, is there any way to submit form but prevent redirect without using ajax. As i know, it's impossible to make a request to different domain with ajax.
Solution 1
AJAX is possible across domains. You need the destination domain to set the appropriate headers on the response.
Access-Control-Allow-Origin: yourdomain.com
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: [anything else you might send]
return false from your ajax call or call preventDefault() to prevent the browser from redirecting the page.
Solution 2
Submit to your own server side code and emulate the transaction. However, you mentioned that they don't allow you to mirror it and I don't have details to address this problem. You can submit to your own server either AJAX (without CORS issues and no headers necessary) or normal POST.
Solution 3
Submit it to their server but have their server redirect back to a page on your own site.
Usually there is a way to set this up through whatever API control panel they give you.
Once again, without specific details, I can't directly address the problem
Solution 4
Load up the data in an iframe and submit in the iframe. This may have issues depending on the value of X-Frame-Options or if they have some sort of CSRF token but you should be able to POST a form in the iframe without redirecting the main page. The iframe can be hidden as well and submitted via JS (use submit() method on form--ajax not required)
New
I would imagine you can do something with an iFrame.
So the logic would be:
Have an empty <div> with display:none;
Have a <form action='self.php'>
Submit and preventDefault()
Build a URL with a querystring
Preferably a totally different page newself.php?var1=something&var2=anotherthing
Append an <iframe> to the hidden <div> with the URL+querystring
$('div').append('<iframe src="newself.php?var1=something&var2=anotherthing"><iframe>");
Get stuff from URL and build replica form
Give newself.php some JS to automatically submit the form to the API URL upon document load
Clear the hidden <div> of it's contents to await a new submission
Original
I am leaving this here because someone upvoted while I edited lol
In order to submit to a different domain they would have to open up their server to accept cross-domain POSTs.
So here the logic that you should be looking into:
AJAX submit to your PHP file and do e.preventDefault()
Use PHP to cURL the POST vars to the other domain. SO cURL Questions
Wait for response from other domain
Send a "yay" or "nay" back to your AJAX call
If the main goal is to keep the visitor on your website and submit visitor input to a third party website, you could submit the form to a local php script that performs a cUrl to the third party website.
That way, the data is posted 'under water' without showing all post parameters to your visitors and you get to keep your visitor on your own website.
The only thing is that your payment provider will probably redirect you to different pages depending on the payment result (succes/failure/unreacheable).
On my website I have a registration page which makes an AJAX request to check if a username is available after it has been entered. This file is called check.php and is in the same directory as the registration.php file. When data is posted to check.php it will perform a query at a MySQL database and return how many users it found with that username.
If anybody were to post data to the check.php file they would see the result, too. I need to stop this somehow, I've read on a few answers I need to "authenticate" each request. This is probably a very large topic although I'm not too sure what to search for to find more about it. Is authenticating each request a good way to stop unnecessary username checks? If so I would really appreciate it if anyone could point me in the right direction as to how to do this.
A solution is to generate a unique token in session, and put it in all pages that will contain a form. Post this token on each AJAX request you make.
It is called CSRF protection, Cross-Site Request Forgery.
You can add a protection layer checking the user referer in HTTP headers.
Answer for common case: no - you can't prevent this, since AJAX is just an HTTP-request. It can be sent no matter how you'll protect your server. So if the point is - to protect from 'evil hackers' - there's no way to do this. The correct though is to check/validate anything on server side.
But is it's about only basic check, you can read
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=='xmlhttprequest')
-but be aware - this is also a data, which came from client i.e. it can't be trusted (actually, it's just HTTP-request header, nothing more)
I think you can create a Session variable when the user logs in your aplication and check if this variable has the correct value whe you post something to your 'check.php' file to check if your user is previous authenticate
Missing a lot of info but conceptually I am not sure you are worrying about a real risk. Bottom line is that people can use your form to check if emails exist so it's logical they can use check.php as well. Would be overkill to try and prevent that.
I have one think - you can generate some unique token, store it on SESSION before show the page. Than on each checking you must to add this token to request. check.php must regenerate token and return it new.
But each request can emulate and it not protect you from people, which want to know results of check.php. Nothing protect...
Also you can make mechanism for analyzing ip request for checking
I have an HTML "Contact us" form which I plant on my client's HTML page,this form has an 'action' property with value that leads to my production system.
When my production system gets the form , it runs a vital code that arranges the type of request by type of request and perform some other QA at the code behind..
In case that the page has an error within our production system, we would like to notify the user that completed the form at our clients side that there was an error.
The problem is that when the form was sent we have no way to get back to the first form as a post was fired.
My question is , if there is any way to come back to the same page where the post was sent to the original page so we can notify the error AFTER the page was sent?
In other words, I need the form to be sent to the a address at the action property , and still make the browser stay at the same page.
Thanks.
You could embed a ReturnURL as part of the post data, that would identify where the post came from. Or perhaps embedding a customer code would be a better idea, that way you are not blindly redirecting to a URL (which could be hacked).
I have a use case where i have to post the form data on a particular link and then forward/redirect the request to another link.
For e.g. In my page i have 3 textfields a,b,c and a submit button. On click of Submit i will post the request to say "http://www.abc.com/example" and then redirect the request to "http://www.def.com".
So for the end user after submitting the request he/she will see "http://www.def.com" and will not come to know that what happened in between.
We do not care what the response is from server where request is posted.
Any help/directions in implementing this use case will be highly appreciated.
Thanks.
Regards,
Mayank
Just specify the submit URL in form's action.
<form action="http://www.abc.com/example" method="post">
and let the code behind that URL redirect the request to the desired URL after postprocessing the request; the following example assumes that it's using the Servlet API:
response.sendRedirect("http://www.def.com");
No need for JavaScript here which would not work anyway on JS-disabled clients.
It would be preferable for performance to submit the form to your original server and then redirect to the other URL.
If you can't do this, then you could submit the request via AJAX request and on completion (success or error) change the window.location to the other URL.