Ólafur Sverrir Kjartansson, [email protected]
- 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));
- 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
- Einsog
- nodemon eftir Remy Sharp eitt af þeim
> npm install -g nodemon
...
> nodemon app.js
[nodemon] watching: *.*
[nodemon] starting `app.js`
...
[nodemon] restarting due to changes...
- 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
- HTTP byggir á request—response milli client og server
- Client sendir request á server
- Server framkvæmir aðgerðir og sendir response á client
- 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
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 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
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>
...
- Sendir bæði í request og response
- Heiti og gildi í texta, aðskilið með tvípunkt
Connection: close
- 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
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 formres.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: 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 yfirskrifaContent-Type
header
- 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');
});
- 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
- 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());
- Mikið til af Express middleware fyrir HTTP verkefni og allskonar
- Getum líka notað Connect middleware
- Leysa algeng verkefni og er það örugggara og fljótlegra að treysta á en skrifa sjálf
- 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 – 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 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)
- Í JavaScript:
- 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ðaftp://example.org
líka
- Getum heimsótt
- Höfum alltaf tæknilega rétt fyrir okkur ef við notum URI
- 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/
- 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 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
– einsogGET
, nema vill aðeins fá hausa skilgreinda fyrir auðlindPOST
– Biður server um að taka við einingu í request sem nýrri einingu, skilgreinda með URIPUT
– biður um að eining í request sé geymd undir URI, ef önnur er til nú þegar skal uppfæra hanaDELETE
– biður um að það sem geymt er á URI sé eytt
- Þegar við búum til
<form>
getum við skilgreint hvort við notumGET
eðaPOST
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" action"/get">
<input type="text" name="datsa">
<button>Senda</button>
</form>
app.get('/get', (req, res) => {
res.send(`GET gögn: ${req.query.data}`);
});
- POST gögn koma sem straumur
req
er EventEmitter
- Þ.a.l. ekki jafn handhægt og að lesa GET gögn
<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
á 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 semkey=value
- 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- http://expressjs.com/en/api.html#express.urlencoded
app.use(express.urlencoded({ extended: true }));
- Styður líka
application/json
en við getum ekki útbúið<form>
sem sendir JSON, en getum prófað með cURL- http://expressjs.com/en/api.html#express.json
curl -H "Content-Type: application/json" -d '{"foo": "bar"}' http://localhost:3000/
- Byggt á
body-parser
- 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
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ðamulter.fields()
- Setur skrár í
req.files
- Skilgreinum middleware per route fyrir upload með
app.post('/post',
multer().array('data'),
(req, res, next) => {
console.log(JSON.stringify(req.files));
}
);
- Þ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
- Ekki nóg að nota
- Passa upp á að gögn séu hrein
- Treystum engu frá notanda! Túlkum öll gögn sem óhrein (dirty) þar til hreinsuð (sanitized)
- 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 strengiexpress-validator
gerirvalidator
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) => { /* ... */ }
);