24
Web Basics Willem Visser RW334

Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Embed Size (px)

Citation preview

Page 1: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Web Basics

Willem VisserRW334

Page 2: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Overview

• Basic Browser and Server Interaction– Forms with actions, url encoding and handlers– Parameters– Having more than one handler– GET versus POST

• Templates– Jinja2

• Validation and Escaping

<thanks>Udacity CS253 is the inspiration for a lot of this content</thanks>

Page 3: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Forms with actions

<form action = "/foo"> <input name="q"> <input type="submit"></form>

<form> <input name="q"> <input type="submit"></form>

<form action = ”http://www.google.com/search"> <input name="q"> <input type="submit"></form>

Page 4: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Server side• How do we react to the “action”?

import webapp2

class MainPage(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, RW334 World!')

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

…handlers:- url: /.* script: main.app…

Main.py

app.yam

l

Page 5: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Server Handler (1)• Lets first add the form to our web page

import webapp2

form = """ <form action = "/foo"> <input name="q"> <input type="submit"></form> """

class MainPage(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(form)

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Will this render the form?

Page 6: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Server Handler (2)• Default content type is HTML

import webapp2

form = """ <form action = "/foo"> <input name="q"> <input type="submit"></form> """

class MainPage(webapp2.RequestHandler): def get(self): #self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(form)

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Will this correctly submit?

Page 7: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Server Handler (3)• Add the FooPage handler whenever the “/foo”

url is accessed on our server• Can get the “q” parameter from the GET request

…class FooPage(webapp2.RequestHandler): def get(self): q = self.request.get("q") self.response.out.write("Thanks for %s" % q)

app = webapp2.WSGIApplication([('/', MainPage), ('/foo', FooPage)], debug=True)

Page 8: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Server Handler (4)

class FooPage(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(self.request)

app = webapp2.WSGIApplication([('/', MainPage), ('/foo', FooPage)], debug=True)

GET /foo?q=blah HTTP/1.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language: en-US,en;q=0.8,af;q=0.6Host: localhost:8080Referer: http://localhost:8080/User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36X-Appengine-Country: ZZ

Page 9: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

GET versus POST…form = """ <form method = “post” action = "/foo"> <input name="q"> <input type="submit"></form> """

class MainPage(webapp2.RequestHandler): def get(self): self.response.out.write(form)

class FooPage(webapp2.RequestHandler): def get(self): q = self.request.get("q") self.response.out.write("Thanks for %s" % q)

app = webapp2.WSGIApplication([('/', MainPage), ('/foo', FooPage)], debug=True)

Will this correctly submit?

Page 10: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

GET versus POST (2)…form = """ <form method = “post” action = "/foo"> <input name="q"> <input type="submit"></form> """

class MainPage(webapp2.RequestHandler): def get(self): self.response.out.write(form)

class FooPage(webapp2.RequestHandler): def post(self): q = self.request.get("q") self.response.out.write("Thanks for %s" % q)

app = webapp2.WSGIApplication([('/', MainPage), ('/foo', FooPage)], debug=True)

Where did the parameter go in url?

Page 11: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

• Parameter now part of the body of request

GET versus POST (3)

POST /foo HTTP/1.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Language: en-US,en;q=0.8,af;q=0.6Content-Length: 6Content-Type: application/x-www-form-urlencodedContent_Length: 6Content_Type: application/x-www-form-urlencodedHost: localhost:8080Origin: http://localhost:8080Referer: http://localhost:8080/User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36X-Appengine-Country: ZZ

q=blah

Page 12: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

GET versus POST (4)• GET

– Parameters in URL• Length restrictions

– Used for fetching documents– OK to cache

• Same request in succession should produce the same

– Should not change the server

• POST– Parameters in body– Used for updating (server)– No caching

Page 13: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Templates

• Greatly simplify developing dynamic websites• Pass data variables to the page• Embed programming constructs in the page• Lots of options, we will use jinja2

Page 14: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

First create your Template<!DOCTYPE html><html> <head> <title>I'm using Templates!</title> </head> <body> I'm {{name}}, and I {{verb}} RW334! </body></html>

…libraries:- name: jinja2 version: latest…ap

p.yam

lbase.htm

l

Page 15: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Handlerimport osimport webapp2import jinja2

jinja_environment = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))

class MainPage(webapp2.RequestHandler): def get(self): template_values = { 'name': 'Willem', 'verb': 'love' }

template = jinja_environment.get_template('base.html') self.response.out.write(template.render(template_values))

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Page 16: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Loops!<!DOCTYPE html><html> <head> <title>I'm using Templates!</title> </head> <body> I'm {{name}}, and I {{verb}} RW334! Here are a few of my favourite things about the course: <ul> {% for item in favourites %} <li>{{ item }}</li> {% endfor %} </ul> </body></html>

Page 17: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Handler…class MainPage(webapp2.RequestHandler): def get(self): template_values = { 'name': 'Willem', 'verb': 'love', 'favourites' : favourites }

template = jinja_environment.get_template('base.html') self.response.out.write(template.render(template_values))

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Page 18: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Validation

• When you receive input it is important to validate it

• Can happen on the client and the server• We will look at it on the server side here

Page 19: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Birthday<!DOCTYPE html><html> <head> <title>Validation</title> </head> <body> <form method = "post"> What is your birthday? <br> <label> Month <input type = "text" name = "month" value="{{month}}”> </label> <label> Day <input type = "text" name = "day" value="{{day}}”> </label> <label> Year <input type = "text" name = "year" value = "{{year}}”> </label> <div style="color: red"> {{error}} </div> <br><br> <input type = "submit"> </form> </body></html>

Page 20: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Handler with Validationclass MainPage(webapp2.RequestHandler): def displayform(self, error = "", month = "", day = "", year = ""): values = dict([('error', error), ('month', month), ('day', day), ('year', year)]) template = jinja_environment.get_template('validation.html') self.response.out.write(template.render(values)) def get(self): self.displayform() def post(self): user_month = self.request.get("month") user_day = self.request.get("day") user_year = self.request.get("year") month = valid_month(user_month) day = valid_day(user_day) year = valid_year(user_year) if not(month and day and year): self.displayform("Not a valid date", user_month, user_day, user_year) else: self.response.out.write("Thanks for the valid birthday")

Page 21: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Escaping• What happens if we add this in a field

– yaya”>oops!

• We need to make sure HTML characters display as intended not mess with the “real” HTML

• This is done by Escaping the HTML– Convert it to something harmless

• Common cases– “ becomes &quot and & becomes &amp– > becomes &gt and < becomes &lt

Page 22: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Escaping Example

• If we want to display this line in the browser– How do we display <html> in HTML?

• By typing– How do we display &lthtml&gt in HTML?

Page 23: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

First Rule of Escaping

NEVER ROLL YOUR OWN!

Page 24: Web Basics Willem Visser RW334. Overview Basic Browser and Server Interaction – Forms with actions, url encoding and handlers – Parameters – Having more

Escape Libsimport cgidef escape_html(s): return cgi.escape(s,quote = True)

class MainPage(webapp2.RequestHandler): def displayform(self, error = "", month = "", day = "", year = ""): values = dict([('error', error),

('month', escape_html(month)), ('day', escape_html(day)), ('year', escape_html(year))])

template = jinja_environment.get_template('validation.html') self.response.out.write(template.render(values))

jinja_environment = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))

OR