Redirecting to a cutted URL in Pyramid - python

I got an URL like: http://localhost:4284/?session_expired=true
Now I'm sending and AJAX-Request for something and the return should be a HTTPFound with 'http://localhost:4284/'.
Cutting the URL is not the problem, but either Pyramid or the Browser are ignoring the changes, so the keep the parameter session_expired in the window location :(
Thanks

AJAX requests do not affect the window location (I suppose you want the browser to go to a completely new page as a result of the AJAX request, so the address in browser's address bar changes).
You can do this manually in JavaScript when handling the response of the AJAX request:
$.ajax(
...
}.done(function (data) {
if (data.redirect_to) {
window.location = data.redirect_to;
}
});
In the example above the server returned 200 Ok status with a JSON response which looks something like {"redirect_to": "http://localhost:4284/"}. You may prefer to return a different HTTP status and handle it in the error handler instead.

If you are returning an HTTPFound-Object, do not parse it as JSON, but rather parse is as HTML!

Related

Python flask API Return the cookies but set in browser

I have an application in which the python flask API and angular frontend is used I'm able to set cookies and receive in frontend header but unable to fetch the value as shown in below images
the code for python flash is as follows
response.set_cookie('token', secret_token, max_age=900, samesite='Lax')
response.set_cookie('region', user.MMUCode)
response.headers.add('Access-Control-Allow-Headers',
"Origin, X-Requested-With, Content-Type, Accept, x-auth")
return response
Here in angular the code is as follows
return this.httpClient.post<any>(apiUrl + APIRoutes.GenerateOTP, data,
{ observe: 'response' }).pipe(map(response => {
console.log(response.headers.keys()); // all header names
return response.body;
}))
But the response header is having the cookies as shown in below images but not getting set as cookies in browser
Please help me with this. Thanks in advance.
Add a sentence before you add it to the response: cookie.setpath("/");

How to handle GET requests with Python CGI and send a Response back

I would like to make a GET request to one of my Python CGI files and get a response back, is there a way to handle that with raw CGI? if not, what other tool would you recommend that could potentially solve this issue? (Flask maybe?)
This is needed so I can give the backend a string to sign and return the newly created signed string back to me.
test.html -- This is what's making a GET request to gethandle.py
<script>
$.getJSON('gethandle.py', some_data, () => {alert('done')})
</script>
gethandle.py -- This is my CGI script that should do things with the request and send a response, this is the part where I am not sure what to do.
#get some_data and do things with it
#send back other_data
as it is now; when inspecting the Network tab on the browser Inspector, I see the request made to gethandle.py from test.html with a 200 status but the response is raw gethandle.py file

Python CGI output contains the Angular ajax request object

When I post data using Angularjs to a Python CGI script, I have a weird issue where the Python output contains an Angular object that I can't remove.
The Angular Javascript responsible for posting to the Python script:
$http({
method: 'POST',
url: '/cgi-bin/test.py',
data: "test"
})
.then(function(data){
console.log(data)
})
The Python script:
#!/usr/local/bin/python2.7
print "Content-type: application/json"
print
The resulting console log should be empty, but this is what I see in the Chrome console:
I'm new to Python and Angular so I suspect that I've made a simple mistake, but I've been unable to find examples of this kind of behavior anywhere after a day of searching. Any help is appreciated.
Coming from jQuery's ajax, I expected the response from Angular's http function to include only the returned data, so I was thrown off by the presence of config, status, header data, etc.
In order to isolate the data part of the response, I did this:
.then(function(response){
data = response['data']
console.log(data)
})

Responding to AJAX GET and POST requests with Google App Engine (Python)

I have confusion on how the servers(here app engine) respond to AJAX GET and POST requests. I want send a GET request to my server and get some JSON data back.
Here is the AJAX GET request
function syncRestoreLinks(e) {
var request = new XMLHttpRequest();
var url = "/sync"
request.open("GET", url);
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function() {
if (request.readyState === 4) {
console.log(request.responseText);
}
}
request.send(null);
console.log("Getting links from db");
}
Handler on the server side
class SyncHandler(Handler):
def get(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
def post(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
This handler writes my response data out to the screen where as I want it to send it back and let JS handle it. (I am able to use server redirects here.)
If I make a POST request instead, the code works the way I intend it to. But here, I cannot make server redirects or render pages and only the script making request has that control.
Is this how GET/POST responses work or I am doing something stupid in my code?
Is there any way for GET response not to be written on the page and be sent to JS? In the code above the responseText is an empty string but, the json is printed on screen.
I'm doing AJAX Get requests successfully with app engine right now.
Your sync handler looks correct. Are you sure it is being called? Add a logging.info() statement there to make sure. If it is being called, then I suspect the error is on the front end. I use jQuery and not XMLHttpRequest so I can't you help you with that. My jQuery call looks like this:
$.get(url, callback_function, 'json');
You can add a POST handler to your SyncHandler like this:
def post(self):
...
self.response.out.write(json_txt)
The strange part is that your POST request should not be working without this code to handle the request. You only show a get() method in your code.

CORS - Using AJAX to post on a Python (webapp2) web service

This is going to be long:
Ok so I'm developing a google calendar gadget which sends requests to a Python webapp2 REST api hosted on Google App Engine.
The problem comes when I try to POST something it doesn't allows me because of CORS.
In Chromes' DevTools it says:
Method: OPTIONS.
Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
Origin https://hq34i4geprnp5vci191ljfuhcoerscl4-a-calendar-opensocial.googleusercontent.com is not allowed by Access-Control-Allow-Origin.
I'm aware that this is because of CORS. Here:
Ajax - 'Origin localhost is not allowed by Access-Control-Allow-Origin'
It says that I have to add
Access-Control-Allow-Origin: *
To the headers, but then again I'm new to ajax and I wonder if it's done this way:
$.ajax({
type: "POST",
url: "https://myapp.appspot.com/service",
contentType: "application/json; charset=utf-8",
data: data,
beforeSend: function (request)
{
request.setRequestHeader("Access-Control-Allow-Origin", "*");
}
success: function(data) {
alert("AJAX done");
}
});
Adding this headers the output is different (which makes me wonder if the origin has been allowed, though I don't really know):
Method: OPTIONS.
Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
XMLHttpRequest cannot load https://myapp.appspot.com/service. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers.
I've even found this:
http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
Which lets me do GET requests, but I'd like to learn how to do them without this.
Also on my webserver I have this:
...
class webService(webapp2.RequestHandler):
options(self):
self.response.write('options')
post(self):
self.response.write('post')
application = webapp2.WSGIApplication([
('/', MainPage),
('/service', webService)
], debug=True)
I don't know if I must add something more to the webserver, nor I've found info saying that I have to.
Also I think I'm near to achieve the CORS request but, I can't find THE Example that explains it all.
Please help.
Ok I fixed it.
First of all I realized here that the headers were sent by the server so I was doing wrong when sending those headers in the AJAX request.
Finally, after searching around the worldwide web I found what I was missing. It was something stupid. I found the page that fixed it all:
http://enable-cors.org/server_appengine.html
So finally everything looks like this:
$.ajax({
type: "POST",
url: "https://myapp.appspot.com/service",
contentType: "application/json; charset=utf-8",
data: data,
success: function(data) {
alert("AJAX done");
}
});
And in the webService:
class webService(webapp2.RequestHandler):
def get(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers['Content-Type'] = 'application/json'
# do something
def post(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers['Content-Type'] = 'application/json'
# do something
def options(self):
self.response.headers['Access-Control-Allow-Origin'] = '*'
self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'
I just want to point out a detail that might help others:
Browsers differ in how they handle the "Access-Control-Allow-Orgin" header. For example, I found that Chrome blocks cross domain posts when the header value is a wildcard (*) as in the solution code above. It considers it too liberal and wants a specific origin. Yet, other browsers such as IE and FireFox did not care.
So if you want to build a cross browser solution it would be best set the value of "Access-Control-Allow-Origin" to the Origin value sent with the request.
If you're using SSL then you'll encounter some other differences that will need to be tested as well.
And if you need a lightweight solution this can all be done with POJS (plain-old-JavaScript) without resorting to jQuery. Just wire up the window.XDomainRequest for IE8+ and the window.XMLHttpRequest for other browsers and you're in business.
Can simpler with dispatch method
class BaseRequestHandler(webapp2.RequestHandler):
def dispatch(self):
self.response.headers.add_header('Access-Control-Allow-Origin', '*')
self.response.headers.add_header('Access-Control-Allow-Headers', 'Content-Type')
webapp2.RequestHandler.dispatch(self)
class LoginHandler(BaseRequestHandler):
def login(self):
#code here

Categories