Skip to content

Latest commit

 

History

History
437 lines (307 loc) · 11.8 KB

03.1.http.form.md

File metadata and controls

437 lines (307 loc) · 11.8 KB

Fyrirlestur 3.1 — HTTP & form

Vefforritun 2 — HBV403G

Ólafur Sverrir Kjartansson, [email protected]


Express async await

  • Ef við notum async await í Express middleware þurfum við að passa upp á að grípa villur
  • Getum gert per middleware eða búið til higher order fall sem sér almennt um
  • Wes Bos: Async await

function catchErrors(fn) {
  return function (req, res, next) {
    return fn(req, res, next).catch(next);
  }
}
app.get('/', catchErrors(asyncMiddleware));

Express og sjálfvirkt restart

  • Getur orðið hvimleitt að handvirkt drepa og kveikja aftur á vefþjón í þróun
  • Til slatti af tólum sem fylgjast með og restarta fyrir okkur
    • Einsog browser-sync en fyrir bakenda
  • nodemon eftir Remy Sharp eitt af þeim

nodemon

> npm install -g nodemon
...
> nodemon app.js
[nodemon] watching: *.*
[nodemon] starting `app.js`
...
[nodemon] restarting due to changes...

HTTP grunnur

  • HTTP 1.1 mest notað í dag
    • HTTP 2 þó að sækja í sig veðrið
  • Notar TCP/IP fyrir gagnafluttning
  • DNS (Domain Name System) þýðir IP-tölur í lén

Request—response

  • HTTP byggir á request—response milli client og server
  • Client sendir request á server
  • Server framkvæmir aðgerðir og sendir response á client

Request

  • Request er:
    • Request line: aðferð (eða sögn) sem notuð er, auðlind og útgáfu af HTTP
    • Headers fyrir aðgerð
    • Tóm lína
    • Hugsanlega gögn

Request – dæmi

GET / HTTP/1.1
Host: example.org
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,...
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) ...
Referer: https://www.google.is/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,is;q=0.6,nb;q=0.4

Response

  • Response er:
    • Status lína: útgáfa af HTTP, staða sem tala og staða sem texti
    • Headers frá þjóni
    • Tóm lína
    • Hugsanlega gögn

Response – dæmi

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Etag: "3f80f-1b6-3e1cb03b"
Content-Type: text/html; charset=UTF-8
Content-Length: 131
Connection: close

<html>
...

Headers

  • Sendir bæði í request og response
  • Heiti og gildi í texta, aðskilið með tvípunkt
    • Connection: close

Express og headers

  • Getum sett headers í response
    • res.set(key, value);
  • Ættum yfirleitt ekki að þurfa að setja sjálf
  • En kemur fyrir að við viljum eiga við

Content-Type

  • Content-Type header segir til um af hvaða gerð gögn eru, bæði í request og reponse
  • Í request er Content-Type sett ef við erum að senda form
    • res.type() er hjálparfall sem setur content-type
  • Í response segir það til um hvaða tegund er á efni sem kemur og hvaða charset það er í

Content-Type og charset

  • Content-Type: text/html
  • Content-Type: text/html; charset=utf-8
  • Ef charset er sett í Content-Type hefur það hærri forgang en það sem skilgreint er í <meta charset>
  • res.send() mun alltaf yfirskrifa Content-Type header

Content-Disposition

  • Ef við viljum að route bjóði upp á að downloada skrá í staðinn fyrir að lesa hana inline
  • Notum þá Content-Disposition header
  • Content-Disposition: attachment; filename=foo.txt

app.get('/download', (req, res) => {
  const filename = 'test.txt';
  res.set('Content-Disposition',
          `attachment; filename="${filename}"`);
  res.send('hello world');
});

Þjöppun

  • Client getur tilgreint að hann styðji þjöppun á gögnum með haus, t.d.:
    • Accept-Encoding: gzip, deflate
  • Ef server hefur þjappað efnið, lætur hann vita af því, t.d.:
    • Content-Encoding: gzip
  • Getur skipt miklu fyrir hraða vefs

Express og þjöppun

  • Til compression middleware sem sér um að þjappa efnið sem við sendum frá okkur
  • Sækjum með NPM og „notum“ ofarlega í app
    • npm install --save compression
    • app.use(compression());

Önnur Express middleware


URI

  • Skilgreint í RFC 3986
  • Uniform Resource Identifier – strengur sem skilgreinir auðlind
    • Með nafni, staðsetningu eða bæði
    • Auðlind er einhver eining sem við viljum nálgast, t.d. HTML skjal, mynd

URN og URL

  • URN – Uniform Resource Name, skilgreinir auðlind með nafni, t.d. ISBN númer
  • URL – Uniform Resource Locator, skilgreinir auðlind með staðsetningu

“A URI can be further classified as a locator, a name, or both. The term "Uniform Resource Locator" (URL) refers to the subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism (e.g., its network "location").” – RFC 3986: URI, URL, and URN


URL

  • URL samanstendur af:
    • Skema (prótokol), tvípunkti & tveimur skástrikum
    • Host, venjulega domain nafn eða IP tala
    • Hugsanlega tvípunkti og port-númeri, ef ekki skilgreint er port 80 notað
    • Slóð á auðlind
    • Hugsanlega query-streng, name-value safn, skipt með &
    • Hugsanlega fragment identifier, staðsetning innan auðlindar

  • Dæmi:
    • scheme://domain:port/path?query_string#fragment_id
    • http://example.org/example?foo=bar#baz
  • Sérstaka (ekki-ASCII) stafi þarf að umrita í URLum til að passa að þeir berist rétt, flest forritunarmál hafa föll sem gera það
    • Í JavaScript: encodeURI(URL)

URI vs URL

  • Getum hugsað um URI sem nafn hlutsins og URL sem heimilisfang
  • example.org er URI, https://example.org er URL og URI
    • Getum heimsótt example.org á http://example.org eða ftp://example.org líka
  • Höfum alltaf tæknilega rétt fyrir okkur ef við notum URI

cURL

  • Command line tól til að gera HTTP aðgerðir
  • Mikið notað til að gera allskonar hluti, sækja efni, læra HTTP, debugga HTTP
  • https://curl.haxx.se/

cURL dæmi

  • Sækja síðu með GET og fá efni til baka: curl http://hi.is
  • Sækja headers með GET: curl --head http://hi.is
  • Sjá hvað er gerast: curl --verbose http://hi.is
  • Senda gögn með POST: curl --data "foo=bar" http://example.org
  • Sjá fleiri í tutorial

HTTP aðferðir

  • HTTP Request þarf að hafa aðferð/sögn tilgreinda
  • HTTP 1.0 skilgreindi GET, POST og HEAD
  • HTTP 1.1 bætti við OPTIONS, PUT, DELETE, TRACE og CONNECT

  • GET – biður um útgáfu af tilgreindri auðlind, lang mest notaða aðferðin!
  • HEAD – einsog GET, nema vill aðeins fá hausa skilgreinda fyrir auðlind
  • POST – Biður server um að taka við einingu í request sem nýrri einingu, skilgreinda með URI
  • PUT – biður um að eining í request sé geymd undir URI, ef önnur er til nú þegar skal uppfæra hana
  • DELETE – biður um að það sem geymt er á URI sé eytt

HTTP aðferðir og <form>

  • Þegar við búum til <form> getum við skilgreint hvort við notum GET eða POST með method attribute
  • <form method="get"> sendir gögn með GET og setur allar breytur í query-string, t.d. http://example.org/?foo=bar
  • <form method="post"> sendir gögn með POST og setur allar breytur í request body

<form method="get">

<form method="get" action"/get">
  <input type="text" name="datsa">
  <button>Senda</button>
</form>

app.get('/get', (req, res) => {
  res.send(`GET gögn: ${req.query.data}`);
});

Express og POST

  • POST gögn koma sem straumur
    • req er EventEmitter
  • Þ.a.l. ekki jafn handhægt og að lesa GET gögn

<form method="post">

<form method="post" action"">
  <label>Foo: <input type="text" name="foo"></label>
  <button>Senda</button>
</form>

app.use((req, res, next) => {
  const chunks = [];
  req.on('data', chunk => chunks.push(chunk));
  req.on('end', () => {
    req.body = chunks.join();
    next();
  });
});

app.post('/post', (req, res) => {
  res.send(`POST gögn: ${req.body}`);
});

When a form is submitted, the data in the form is converted into the structure specified by the enctype, and then sent to the destination specified by the action using the given method.

HTML5.1: 4.10.22 Form submission


enctype

  • enctype á formi segir til um hvernig gögn í formi eru enkóðuð (encoding type)
    • application/x-www-form-urlencoded sjálfgefið, gögn eru URL enkóðuð (t.d. ó verður %C3%B3)
    • multipart/form-data, gögnum er streymt yfir með boundaries, notum þegar við höfum <input type="file">
    • text/plain, ekki er átt við gögnin, þau eru sett sem key=value

body-parser middleware

  • Vesen að vinna með POST gögn gegnum straum í hvert skipti
  • Express 4.16+ hefur urlencoded parser middleware til að vinna með application/x-www-form-urlencoded gögn


Unnið með skrár

  • Ef við viljum taka við skrám þurfum við eitthvað annað
    • body-parser styður ekki—"This does not handle multipart bodies, due to their complex and typically large nature."

multer

  • multer er pakki sem þáttar skrár og gerir aðgengilegar á einfaldan hátt
    • Skilgreinum middleware per route fyrir upload með multer().single(), multer().array() eða multer.fields()
    • Setur skrár í req.files

app.post('/post',
  multer().array('data'),
  (req, res, next) => {
    console.log(JSON.stringify(req.files));
  }
);

Unnið með gögn

  • Þegar við tökum við gögnum úr formi er það yfirleitt frekar mikil handavinna
  • Verðum að staðfesta að gögn séu gild á bakenda!
    • Ekki nóg að nota <input required> eða JavaScript á framenda
  • Passa upp á að gögn séu hrein
    • Treystum engu frá notanda! Túlkum öll gögn sem óhrein (dirty) þar til hreinsuð (sanitized)

Validation

  • Getum og ættum að nýta okkur treyst forritasöfn til að staðfesta (validate) og hreinsa (santize) gögn
  • validator sér um að staðfesta og hreinsa strengi
  • express-validator gerir validator aðgengilegt gegnum middleware

app.post(
  '/data',
  check('email')
    .isLength({ min: 1})
    .withMessage('Netfang má ekki vera tómt'),
  check('email')
    .isEmail()
    .withMessage('Netfang verður að vera netfang'),
  (req, res) => { /* ... */ }
);