noob question about redirections

27 views
Skip to first unread message

jg...@live.com.mx

unread,
Jul 17, 2018, 12:45:26 AM7/17/18
to pylons-discuss
hi everyone.

i am trying to do this simple? thing:
. in a test page ("/test") send some parameters to the server using POST
. when the view detects those paremeters, redirect to home ("/")

i can get this to work but only if i post the values using a form, it does not work if i run a javascript function calling a xmlhttprequest.

i used the cookiecutter-starter and added some lines.

**__init__.py**

from pyramid.config import Configurator


def main(global_config, **settings):
   
""" This function returns a Pyramid WSGI application.
    """

    config
= Configurator(settings=settings)
    config
.include('pyramid_chameleon')
    config
.add_static_view('static', 'static', cache_max_age=0)
    config
.add_route('home', '/')
    config
.add_route('test', '/test')
    config
.scan()
   
return config.make_wsgi_app()





**views.py**
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound,HTTPSeeOther


@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
   
print("in my view")
   
return {'project': 'project'}


@view_config(route_name='test', renderer='templates/jg.pt')
def y_view(request):
    prm_0
= request.POST.get("prm_0",None)
    prm_1
= request.POST.get("prm_1",None)
   
if prm_0 and prm_1:
       
print("parameters present")
       
return HTTPFound(location=request.route_url("home"))
   
else:
       
print("no parameters found")
   
return {}





**templates/jg.pt**
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:tal="http://xml.zope.org/namespaces/tal" xml:lang="es" lang="es">
<head>
   
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   
<title>n</title>
   
<script type="text/javascript">
   
function postit(){
        console
.log("pompom");
       
var xhr = new XMLHttpRequest();
        xhr
.open("POST", '/test', true);
        xhr
.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr
.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        xhr
.send("prm_0=898&prm_1=603");
   
}
   
</script>
</head>
<body>
    using XMLHttpRequest..
   
<br/>
   
<button onclick="postit()">through xmlhttprequest</button>
   
<br/>
    wrapped in a form...
   
<form method="POST">
       
<input type="hidden" name="prm_0" value="3455">
       
<input type="hidden" name="prm_1" value="6778">
       
<button type="submit">in-form</button>
   
</form>
</body>






When i press the button for the xhr i see in browser development tool 2 requests:
    . name=test, status=302, type=text,html
    . name=localhost, status=200, type=xhr
i can see in the console that the view callable for home is called (prints "in my view") but it does not render.

Now, when i press the form button i see in browser development tools many requests, being the most important:
    . name=test, status=302, type=text,html
    . name=localhost, status=200, type=document
and this time it does render the home page.

I tried adjusting the xhr so the headers look like the other request..

request header sent using xhr button..
..for test page
POST /test HTTP/1.1
Host: localhost:6543
Connection: keep-alive
Content-Length: 19
Pragma: no-cache
Cache-Control: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Origin: http://localhost:6543
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:6543/test
Accept-Encoding: gzip, deflate, br
Accept-Language: es-419,es;q=0.9
Cookie: pdtb_active=performance




..for home page
GET / HTTP/1.1
Host: localhost:6543
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54
Referer: http://localhost:6543/test
Accept-Encoding: gzip, deflate, br
Accept-Language: es-419,es;q=0.9
Cookie: pdtb_active=performance





now using the form button..
..for test page
POST /test HTTP/1.1
Host: localhost:6543
Connection: keep-alive
Content-Length: 21
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:6543
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:6543/test
Accept-Encoding: gzip, deflate, br
Accept-Language: es-419,es;q=0.9
Cookie: pdtb_active=performance




..home page
GET / HTTP/1.1
Host: localhost:6543
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:6543/test
Accept-Encoding: gzip, deflate, br
Accept-Language: es-419,es;q=0.9
Cookie: pdtb_active=performance





they looks the same! why is one interpreted as xhr and other as document?
i am thinking that if i get the xhr-button generated request to be treated as document it may be rendered well, am i right? is this it? i think i read somewhere that the page is not rendered because of the raised exception (httpfound) but if it is so, how or when will it work?
in stackoverflow some suggested using "render_to_response" or "subrequests", i tried without success and looking at the examples, none of them uses declarative style for the views, what makes me think that the response that these options generate can not be handled right by the renderer.

what is the correct way of accomplishing this? should i stick to forms? why does it work but the other does not?

thanks.

Steve Piercy

unread,
Jul 17, 2018, 1:04:27 AM7/17/18
to pylons-...@googlegroups.com
What's in your templates/mytemplate.pt?

It should contain something that can display the dict that you
return to it. See:
https://chameleon.readthedocs.io/en/latest/reference.html#tal-content

I would suggest that you return a variable to which you assign
the dict, then return the variable, so that it is easier to work
with in the templating language.

--steve


On 7/16/18 at 9:03 PM, jg...@live.com.mx pronounced:
------------------------
Steve Piercy, Eugene, OR

jg...@live.com.mx

unread,
Jul 17, 2018, 1:42:21 AM7/17/18
to pylons-...@googlegroups.com
thanks for replying.
my template.pt is the home page for the cookiecutter-starter. the big red
pyramid page.
i am not with the computer now, i will put those values in the template as
you suggest. anyway, the fact that it works without problem when POSTing
thru the form makes me think that it is not relevant to this behavior. dont
you think?

En 17 de julio de 2018 12:04:28 a.m. Steve Piercy
<steve.pi...@gmail.com> escribió:
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to pylons-discus...@googlegroups.com.
> To post to this group, send email to pylons-...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pylons-discuss/r480Ps-10126i-32DD1BA877EB412B94032953BE161BE9%40Steves-iMac.local.
> For more options, visit https://groups.google.com/d/optout.


Enviado con AquaMail para Android
https://www.mobisystems.com/aqua-mail


Steve Piercy

unread,
Jul 17, 2018, 2:54:42 AM7/17/18
to pylons-...@googlegroups.com
Assuming this is the issue:

>>>i can see in the console that the view callable for home is
>>>called (prints "in my view") but it does not render.

If you want to render the values passed into templates, they
must have "slots" to accept those values. How else will the
template know where it should be inserted?

The default template from pyramid-cookiecutter-starter has no
defined slots, and does not accept or display arbitrary return
values. You must add them.

Also using the headers you provided for each request, sorting
them, then use diff to compare them, you will discover they are
identical except for one:

>>>request header sent using xhr button..
>>>..for test page
>>>Content-Length: 19
>>>
>>>now using the form button..
>>>..for test page
>>>Content-Length: 21

...which is reasonable.

--steve


On 7/17/18 at 5:42 AM, jg...@live.com.mx pronounced:
Message has been deleted

jg...@live.com.mx

unread,
Jul 17, 2018, 12:50:17 PM7/17/18
to pylons-...@googlegroups.com
@steve.percy
i did what you suggest,i passed the params in the query, retrieve them in the home view and place them in the template, but it is the same. maybe i did not explained myself: the page does not render at all, it shows "print" message in the view callable, it shows as xhr in the browser development tool but in browserdoes not change url nor displays the page.

@jvanasco
i changed the javascript to this:

<script type="text/javascript">
function postit(){
console.log("pompom");
var xhr = new XMLHttpRequest();
xhr.open("POST", '/test', true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
xhr.setRequestHeader("Upgrade-Insecure-Requests", 1);
xhr.send("prm_0=898&prm_1=603");
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
window.location.replace("/");
}
};
}
</script>

and it worked! thanks.


so, to make this clear to me: the POST made from javascript is not equivalent to a POST made in html, the hmtl POST automatically refreshs page or something like that?

thanks to both of you.









En Tue, 17 Jul 2018 02:45:07 -0500, Jonathan Vanasco <jvan...@gmail.com> escribió:

the issue is in your javascript; the browser will never render the template on this setup.

when you view /test via GET (or missing one or more required POST items), templates/jg.pt is rendered.
when you view /test via POST with both variables present, the response is a redirect (HTTPFound)

your javascript submits "form data" but it's not submitting the form for the browser.  the response from pyramid is lost in javascript.

your flow is this:

    * browser-tab GET /test 
    ** browser-tab's javascript POST /test 
    ** pyramid redirect to /home
    ** browser-tab's javascript ???

in this flow, the browser tab doesn't POST, the javascript engine in the tab does.

because the POST happens within javascript, you need to use javascript to decide what to do.

typically before hitting send, one would define a callback hook for the xhr object, something like explained  here: https://www.w3schools.com/xml/xml_http.asp

  xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      // do something with this.responseText;
      console.log('got response');
    }
  };


--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To post to this group, send email to pylons-...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
JG

jg...@live.com.mx

unread,
Jul 17, 2018, 12:50:35 PM7/17/18
to pylons-discuss
@steve.percy
i did what you suggest,i passed the params in the query, retrieve them in the home view and place them in the template, but it is the same. maybe i did not explained myself: the page does not render at all, it shows "print" message in the view callable, it shows as xhr in the browser development tool but in browserdoes not change url nor displays the page.

@jvanasco
i changed the javascript to this:
    <script type="text/javascript">
    function postit(){
        console.log("pompom");
        var xhr = new XMLHttpRequest();
        xhr.open("POST", '/test', true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        xhr.setRequestHeader("Upgrade-Insecure-Requests", 1);
        xhr.send("prm_0=898&prm_1=603");
        xhr.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                window.location.replace("/");
            }
        };
    }
    </script>

and it worked! thanks.


so, to make this clear to me: the POST made from javascript is not equivalent to a POST made in html, the hmtl POST automatically refreshs page or something like that?

thanks to both.

Jonathan Vanasco

unread,
Jul 17, 2018, 2:16:59 PM7/17/18
to pylons-discuss

On Tuesday, July 17, 2018 at 12:45:26 AM UTC-4, jg...@live.com.mx wrote:
so, to make this clear to me: the POST made from javascript is not equivalent to a POST made in html, the hmtl POST automatically refreshs page or something like that?

This may sound confusing... but their "equivalence" is based on perspective:

    As far as your Pyramid app is concerned, they are equivalent
    As far as the HTTP Specification is concerned, they are equivalent
    As far as almost everything is concerned... they are equivalent

BUT

    As far as a user is concerned *in this scenario* they are not equivalent.
    Clicking "Submit" to post the form has the browser window post the form and handle the response;
    Clicking your xhr button instructs the browser to do everything within javascript - so javascript is then responsible for posting the form and handling the response.

jg...@live.com.mx

unread,
Jul 17, 2018, 2:36:12 PM7/17/18
to pylons-...@googlegroups.com
thanks for the explanation.

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To post to this group, send email to pylons-...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages