Skip to content

Commit 28df7af

Browse files
committed
Another pass over chapter 17
1 parent 2deb7e9 commit 28df7af

File tree

3 files changed

+99
-93
lines changed

3 files changed

+99
-93
lines changed

10_modules.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ far-away web server, the page would freeze for a painfully long time
481481
while loading its scripts.
482482

483483
One way to work around this problem is to run a program like
484-
_http://browserify.org[Browserify]_ on your code before you serve it
484+
http://browserify.org[_Browserify_] on your code before you serve it
485485
on a web page. This will look for calls to `require` and gather the
486486
dependencies it finds together into a big file. When you actually
487487
serve the code, you only have to call `require` once with this big

17_http.txt

Lines changed: 92 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,24 @@ fact that a hypertext link can point to anything, be it personal,
1414
local or global, be it draft or highly polished.
1515
____
1616

17-
The _Hyper-Text Transfer Protocol_, already mentioned in link:12_browser.html#web[Chapter 12],
18-
is the mechanism through which data is requested and provided on the
19-
World Wide Web. This chapter describes this protocol in more detail,
20-
and explains the way browser JavaScript has access to it.
17+
The _Hyper-Text Transfer Protocol_, already mentioned in
18+
link:12_browser.html#web[Chapter 12], is the mechanism through which
19+
data is requested and provided on the World Wide Web. This chapter
20+
describes the protocol in detail, and explains the way browser
21+
JavaScript has access to it.
2122

2223
== The protocol ==
2324

24-
As an example, imagine you type
25-
_http://eloquentjavascript.net/index.html_ into your browser's address
26-
bar. First, the browser looks up the address of the server associated
27-
with _eloquentjavascript.net_, and tries to open a TCP connection to
28-
it on port 80, the default port for HTTP traffic. If the server
29-
exists, and accepts the connection, the browser sends something like
30-
this:
25+
As an example, imagine you type _eloquentjavascript.net/17_http.html_
26+
into your browser's address bar. First, the browser looks up the
27+
address of the server associated with _eloquentjavascript.net_, and
28+
tries to open a TCP connection to it on port 80, the default port for
29+
HTTP traffic. If the server exists and accepts the connection, the
30+
browser sends something like this:
3131

3232
[source,http]
3333
----
34-
GET /index.html HTTP/1.1
34+
GET /17_http.html HTTP/1.1
3535
Host: eloquentjavascript.net
3636
User-Agent: Your browser's name
3737
----
@@ -57,7 +57,7 @@ with this line:
5757

5858
[source,http]
5959
----
60-
GET /index.html HTTP/1.1
60+
GET /17_http.html HTTP/1.1
6161
----
6262

6363
The first word is the _method_ of the request. `GET` means that we
@@ -72,9 +72,9 @@ applies to. In the simplest case, a resource is simply a file on the
7272
server. But the protocol doesn't require it to be: it may be anything
7373
that can be transferred _as if_ it is a file. Many servers generate
7474
the responses they produce on the fly. For example, if you open
75-
_http://twitter.com/marijnjh_, the server looks in its database for a
76-
user named “marijnjh”, and if it finds one, it will generate a profile
77-
page for that user.
75+
http://twitter.com/marijnjh[_twitter.com/marijnjh_], the server looks
76+
in its database for a user named “marijnjh”, and if it finds one, it
77+
will generate a profile page for that user.
7878

7979
After the resource path, the first line of the request mentions
8080
`HTTP/1.1`, to indicate the version of the HTTP protocol it is using.
@@ -92,8 +92,8 @@ Codes starting with a 2 indicate that the request succeeded. Codes
9292
starting with a 4 mean there was something wrong with the request. 404
9393
is probably the most famous HTTP status code—it means that the
9494
resource that was requested could not be found. Codes that start with
95-
5 mean an error occurred that the server, rather than the request, is
96-
to blame for.
95+
5 mean an error happened on the the server, and the request is not to
96+
blame.
9797

9898
[[headers]]
9999
The first line of a request or response may be followed by any number
@@ -102,14 +102,14 @@ extra information about the request or response. These headers were
102102
part of the example response:
103103

104104
----
105-
Content-Length: 3122
105+
Content-Length: 65585
106106
Content-Type: text/html
107107
Last-Modified: Wed, 09 Apr 2014 10:48:09 GMT
108108
----
109109

110-
This tells us the size and type of the document that is being
111-
returned. In this case, an HTML document of 3122 bytes. It also tells
112-
us when that document was last modified.
110+
This tells us the size and type of the response document. In this
111+
case, an HTML document of 65,585 bytes. It also tells us when that
112+
document was last modified.
113113

114114
Which headers to include in a request or a response is mostly up to
115115
the client or server sending it, though a few are required. For
@@ -128,12 +128,12 @@ error responses, do not require a body.
128128

129129
As we saw in the example, a browser will make a request when we enter
130130
a URL in its address bar. When the resulting HTML page references
131-
other files, such as images and JavaScript files those are also
131+
other files, such as images and JavaScript files, those are also
132132
fetched.
133133

134134
A moderately complicated website can easily include anywhere from ten
135135
to two hundred resources. To be able to fetch those quickly, browsers
136-
will open several requests simultaneously, rather than waiting for the
136+
will make several requests simultaneously, rather than waiting for the
137137
responses one at a time.
138138

139139
Fetching such documents is always done using `GET` requests.
@@ -205,35 +205,35 @@ The link:18_forms.html#forms[next chapter] will come back to forms,
205205
and talk about the way we can script them with JavaScript.
206206

207207
[[xmlhttprequest]]
208-
== Historical accident ==
208+
== XMLHttpRequest ==
209209

210210
The interface through which browser JavaScript can make HTTP requests
211-
is called `XMLHttpRequest` (note the inconsisten capitalization). It
211+
is called `XMLHttpRequest` (note the inconsistent capitalization). It
212212
was designed by Microsoft, for their Internet Explorer browser, in the
213213
late 1990s. During this time, in the world of business software (a
214214
world which Microsoft has always been at home in) the XML file format
215215
was _very_ popular. So popular that the word “XML” was tacked onto the
216216
front of the name of an interface for HTTP, which is in no way tied to
217217
XML.
218218

219-
The name isn't completely nonsensical. There is functionality for
220-
parsing a response as an XML file built into the interface. Confusing
221-
two distinct concepts (making a request and parsing the response) into
222-
a single thing is terrible design, of course, but so it goes.
219+
The name isn't completely nonsensical. The interface allows you to
220+
parse response documents as XML, if you want to. Confusing two
221+
distinct concepts (making a request and parsing the response) into a
222+
single thing is terrible design, of course, but so it goes.
223223

224224
When the `XMLHttpRequest` interface was added to Internet Explorer, it
225225
allowed people to do things with JavaScript that had been very hard
226-
before. One thing that made ripples at the time was the ability to
227-
show suggestions when the user is typing something into a text field.
228-
The script would send the text typed to the server over HTTP, and the
229-
server, which had some database of things that the user might mean,
230-
would match those against the partial input, and send back possible
231-
completions. These were then shown to the user. This was mind-blowing,
232-
at a time where people were used to every interaction with a website
233-
requiring a full page reload.
234-
235-
The other significant browser of the time, Mozilla (later Firefox) did
236-
not want to be left behind. To allow people to do similarly neat
226+
before. For example, websites started showing lists suggestions when
227+
the user was typing something into a text field. The script would send
228+
the text typed to the server over HTTP, and the server, which had some
229+
database of things that the user might mean, would match those against
230+
the partial input, and send back possible completions, which were then
231+
shown to the user. This was considered very spectacular—people were
232+
used to the fact that every interaction with a website required a full
233+
page reload.
234+
235+
The other significant browser at that time, Mozilla (later Firefox)
236+
did not want to be left behind. To allow people to do similarly neat
237237
things in _their_ browser, they copied the interface, including the
238238
bogus name. The next generation of browsers followed this example, and
239239
today `XMLHttpRequest` is a de facto standard interface.
@@ -256,12 +256,12 @@ console.log(req.responseText);
256256

257257
The `open` method configures the request. In this case, we choose to
258258
make a `GET` request for the _example/data.txt_ file. URLs that don't
259-
start with _http://_ are called relative, which means that they are
260-
interpreted relative to the current document. When they start with a
261-
slash (“/”), they replace the current path (the part after the server
262-
name). When they do not, the part of the current path up to and
263-
including its last slash character is put in front of the relative
264-
URL.
259+
start with a protocol (like _http://_) are called relative, which
260+
means that they are interpreted relative to the current document. When
261+
they start with a slash (“/”), they replace the current path (the part
262+
after the server name). When they do not, the part of the current path
263+
up to and including its last slash character is put in front of the
264+
relative URL.
265265

266266
After opening the request, we can send it with the `send` method. The
267267
argument to send is the request body. For `GET` requests, we can pass
@@ -271,10 +271,8 @@ request object's `responseText` property to get the response body.
271271

272272
The other information included in the response can also be extracted
273273
from this object. The status code is accessible through the `status`
274-
property, and the status text through `statusText`. Headers can be
275-
read with `getResponseHeader` (which expects a header name as
276-
argument, and returns the header's value) and `getAllResponseHeaders`
277-
(which returns a string containing all headers).
274+
property, and the human-readable status text through `statusText`.
275+
Headers can be read with `getResponseHeader`.
278276

279277
// test: no
280278

@@ -309,7 +307,7 @@ our program is suspended as long as the browser and server are
309307
communicating. When the connection is bad, the server is slow, or the
310308
file is big, that might take quite a while. Worse, because no event
311309
handlers can fire while our program is suspended, the whole document
312-
will become unresponsive. This is bad.
310+
will become unresponsive.
313311

314312
If we pass `true` as the third argument to `open`, the request is
315313
_asynchronous_. That means that when we call `send`, the only thing
@@ -333,10 +331,12 @@ req.addEventListener("load", function() {
333331
req.send(null);
334332
----
335333

336-
This again forces us to use an asynchronous style of programming,
337-
wrapping the things that have to be done after the request in a
338-
function, and arranging for that to be called at the appropriate time.
339-
We will come back to this link:17_http.html#promises[later].
334+
Just like the use of `requestAnimationFrame` in
335+
link:15_game.html#game[Chapter 15], this forces us to use an
336+
asynchronous style of programming, wrapping the things that have to be
337+
done after the request in a function, and arranging for that to be
338+
called at the appropriate time. We will come back to this
339+
link:17_http.html#promises[later].
340340

341341
== Fetching XML Data ==
342342

@@ -402,10 +402,11 @@ random mafia account.
402402
It is not too hard for websites to protect themselves against such
403403
events, but it requires effort, and many websites fail to do it. For
404404
this reason, browsers protect us by disallowing scripts to make HTTP
405-
requests to other domains (names like _themafia.org_ and _mybank.com_).
405+
requests to other _domains_ (names like _themafia.org_ and
406+
_mybank.com_).
406407

407408
This can be an annoying problem when building systems that want to
408-
access other domains for legitimate reasons. It is possible for
409+
access several domains for legitimate reasons. It is possible for
409410
servers to include a header like this in their response to explicitly
410411
indicate to browsers that it is okay for the request to come from a
411412
different domain:
@@ -440,7 +441,8 @@ function backgroundReadFile(url, callback) {
440441
This simple abstraction makes it easier to use `XMLHttpRequest` for
441442
simple `GET` requests. If you are writing a program that has to make
442443
HTTP requests, it is a good idea to use a helper function, so that you
443-
don't end up repeating the same pattern over and over.
444+
don't end up repeating the ugly `XMLHttpRequest` pattern all through
445+
your code.
444446

445447
The function argument's name, `callback`, is a term that is often used
446448
to describe functions like this. A callback function is given to other
@@ -455,13 +457,13 @@ wrappers for `XMLHttpRequest`.
455457

456458
The main problem with the wrapper above is its handling of failure.
457459
When the request returns a status code that indicates an error (400
458-
and up), it just logs something to the console and bails out.
459-
Sometimes, this is okay, but imagine, for example, we put a “loading”
460-
indicator on the page to indicate that we are fetching information. If
461-
the request fails, because the server crashed or the connection is
462-
briefly interrupted, the page will just sit there, misleadingly
463-
looking like it is doing something. The user will wait for a while,
464-
get impatient, and hate us.
460+
and up), it does nothing. This might be okay, in some circumstances,
461+
but imagine we put a “loading” indicator on the page to indicate that
462+
we are fetching information. If the request fails, because the server
463+
crashed or the connection is briefly interrupted, the page will just
464+
sit there, misleadingly looking like it is doing something. The user
465+
will wait for a while, get impatient, and consider the site uselessly
466+
flaky.
465467

466468
We should also have an option to be notified when the request fails,
467469
so that we can take appropriate action—for example, remove the
@@ -545,18 +547,18 @@ actions.
545547
== Promises ==
546548

547549
For complicated projects, writing asynchronous code in plain callback
548-
back is hard to do correctly. It is easy to forget to check for an
550+
style is hard to do correctly. It is easy to forget to check for an
549551
error, or to allow an unexpected exception to cut the program short in
550552
a crude way. Additionally, arranging for correct error handling when
551553
the error has to flow through multiple callback functions and `catch`
552554
blocks is tedious.
553555

554-
There have been a lot of attempts to solve this with extra
555-
abstractions. One of the most successful ones is called _promises_.
556-
Promises wrap an asynchronous action in an object, which can be passed
557-
around and told to do certain things when the action finishes or
558-
fails. They are set to become a part of the next version of the
559-
JavaScript language, but can already be used as a library.
556+
(((ECMAScript 6)))There have been a lot of attempts to solve this with
557+
extra abstractions. One of the more successful ones is called
558+
_promises_. Promises wrap an asynchronous action in an object, which
559+
can be passed around and told to do certain things when the action
560+
finishes or fails. They are set to become a part of the next version
561+
of the JavaScript language, but can already be used as a library.
560562

561563
The interface for promises is somewhat non-obvious, but very powerful.
562564
This chapter will only roughly describe it. A more thorough treatment
@@ -640,7 +642,7 @@ allowed. The error will be passed on to the promise returned by
640642
`then`, which is exactly what we want—`getJSON` does not know what to
641643
do when something goes wrong, but its caller hopefully does.
642644

643-
As an example of a suitable use of promises, we will build a program
645+
As an example that shows the use of promises, we will build a program
644646
that fetches a number of JSON files from the server, and, while it is
645647
doing that, shows the word “loading”. The JSON files contain
646648
information about people, with links to files that represent other
@@ -684,7 +686,7 @@ the final `then`, which removes the loading message, is always
684686
executed, even if something went wrong.
685687

686688
You can think of the promise interface as implementing its own
687-
language for asynchronous control flow. All the method calls and
689+
language for asynchronous control flow. The extra method calls and
688690
function expressions needed to achieve this make the code look
689691
somewhat awkward, but not remotely as awkward as it would look if we
690692
took care of all the error handing ourselves.
@@ -725,22 +727,22 @@ since resources are easier to reason about than a jumble of functions.
725727

726728
Data traveling over the internet tends to follow a long, dangerous
727729
road. In order to get to its destination it must hop through anything
728-
from open coffee shop wireless networks, to networks controlled by
729-
various companies and states. At any point, it may be inspected, or
730-
even modified.
730+
from coffee shop wifi networks to networks controlled by various
731+
companies and states. At any point along its routed, it may be
732+
inspected, or even modified.
731733

732734
If it is important that something remain secret, such as the password
733735
to your email account, or that it arrive at its destination
734736
unmodified, such as the account number you transfer money to from your
735737
bank's website, plain HTTP is not good enough.
736738

737-
The secure HTTP protocol, whose URLs start with `https:`, wraps HTTP
739+
The secure HTTP protocol, whose URLs start with _https://_, wraps HTTP
738740
traffic in a way that makes it harder to read and tamper with. First,
739741
the client verifies that the server is who it claims to be, by
740742
requiring it to prove that is has a cryptographic certificate issued
741-
by one of the certificate authorities that the browser recognizes.
742-
Next, all data going over the connection is encrypted in a way that
743-
should prevent eavesdropping and tampering.
743+
by a certificate authority that the browser recognizes. Next, all data
744+
going over the connection is encrypted in a way that should prevent
745+
eavesdropping and tampering.
744746

745747
Thus, when it works right, HTTPS prevents both the situation where
746748
someone impersonates the website you were trying to talk to, and the
@@ -795,15 +797,17 @@ repetetive and error-prone elements in this style of programming.
795797

796798
One of the things that HTTP can do, but which we have not discussed in
797799
this chapter yet, is called _content negotiation_. The `Accept` header
798-
in a request can be used to tell the server what type of document the
800+
for a request can be used to tell the server what type of document the
799801
client would like to get. Many servers ignore this header, but when a
800-
server knows of various way to encode a resource, it can look at this
802+
server knows of various ways to encode a resource, it can look at this
801803
header and send the one that the client prefers.
802804

803-
The URL _http://eloquentjavascript.net/author_ is configured to
804-
respond with either plain text, HTML, or JSON, depending on what the
805-
client asks for. These formats are identified by the standardized
806-
_media types_ `text/plain`, `text/html`, and `application/json`.
805+
The URL
806+
http://eloquentjavascript.net/author[_eloquentjavascript.net/author_]
807+
is configured to respond with either plain text, HTML, or JSON,
808+
depending on what the client asks for. These formats are identified by
809+
the standardized _media types_ `text/plain`, `text/html`, and
810+
`application/json`.
807811

808812
Send requests to fetch all three formats of this resource. Use the
809813
`setRequestHeader` method of your `XMLHttpRequest` object set the

20_node.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -975,8 +975,9 @@ when the I/O you asked for is completed.
975975

976976
In link:17_http.html#exercise_accept[Chapter 17], the first exercise
977977
was to make several requests to
978-
_http://eloquentjavascript.net/author_, asking for different types of
979-
content by passing different `Accept` headers.
978+
http://eloquentjavascript.net/author[_eloquentjavascript.net/author_],
979+
asking for different types of content by passing different `Accept`
980+
headers.
980981

981982
Do this again, using Node's `http.request` function. Ask for at least
982983
the media types `text/plain`, `text/html`, and `application/json`.
@@ -1142,8 +1143,9 @@ online for everybody to see.
11421143
You can create a `<textarea>` element to hold the content of the file
11431144
that is being edited. A `GET` request, using `XMLHttpRequest`, can be
11441145
used to get the current content of the file. You can use relative URLs
1145-
like _index.html_, instead of _http://localhost:8000/index.html_, to
1146-
refer to files on the same server as the running script.
1146+
like _index.html_, instead of
1147+
http://localhost:8000/index.html[_http://localhost:8000/index.html_],
1148+
to refer to files on the same server as the running script.
11471149

11481150
Then, when the user clicks a button (you can use a `<form>` element
11491151
and `"submit"` event, or simply a `"click"` handler), make a `PUT`

0 commit comments

Comments
 (0)