1
00:00:01,200 --> 00:00:08,408
Every HTTP message has three parts: a first line, a block of headers, and a body.

2
00:00:08,549 --> 00:00:11,020
Call it the Law of Three.

3
00:00:11,220 --> 00:00:15,073
Links and images ask for things, with an empty body.

4
00:00:15,283 --> 00:00:26,009
A form is the one thing in plain HTML that writes a whole request, body and all, with no JavaScript at all.

5
00:00:26,209 --> 00:00:30,816
Look at the form element, and you can predict the request it will write.

6
00:00:31,027 --> 00:00:35,391
The method attribute and the action fill the first line.

7
00:00:35,601 --> 00:00:39,802
The action's host and the encoding type become headers.

8
00:00:39,943 --> 00:00:44,852
And the fields, walked and encoded, become the body.

9
00:00:45,053 --> 00:00:48,314
Three attributes and some named fields.

10
00:00:48,455 --> 00:00:51,855
Let's watch the browser fill in each part.

11
00:00:52,555 --> 00:00:56,826
The method attribute says what kind of request this is.

12
00:00:56,909 --> 00:01:00,610
Leave it off, and you get GET, the default.

13
00:01:00,810 --> 00:01:03,316
The action says where it goes.

14
00:01:03,341 --> 00:01:08,680
Its path lands in the first line, and its host becomes the Host header.

15
00:01:08,891 --> 00:01:13,184
Write a relative action, and the page's own host fills in.

16
00:01:13,488 --> 00:01:19,512
Leave the action off entirely, and the form submits to the very page it's on.

17
00:01:19,908 --> 00:01:23,645
To say so explicitly, we often write #.

18
00:01:23,786 --> 00:01:32,039
Fun fact: a form that posts to its own page is an old web coding pattern called a postback.

19
00:01:32,239 --> 00:01:49,908
So method="post" and action="https://cse134.site/api/echo" give us POST /api/echo HTTP/1.1, and Host: cse134.site.

20
00:01:50,108 --> 00:01:56,457
HTML forms know only two HTTP methods, GET and POST.

21
00:01:56,853 --> 00:02:03,411
Other HTTP methods like PUT, PATCH and DELETE aren't supported.

22
00:02:03,611 --> 00:02:08,439
Write method="put" anyway, and the browser doesn't complain.

23
00:02:08,464 --> 00:02:11,666
It quietly sends a GET.

24
00:02:11,866 --> 00:02:15,138
There is one more value, dialog.

25
00:02:15,442 --> 00:02:21,837
It sends no request at all; it closes the dialog box the form sits in.

26
00:02:22,048 --> 00:02:25,773
That's a story for another tutorial.

27
00:02:25,973 --> 00:02:29,431
The choice also decides where the data goes.

28
00:02:29,549 --> 00:02:37,825
With GET, the fields ride in the query string, on the first line, in the address bar, in history and in server logs.

29
00:02:37,838 --> 00:02:40,507
With POST, they travel in the body.

30
00:02:40,625 --> 00:02:42,608
GET asks a question.

31
00:02:42,796 --> 00:02:45,081
POST makes a change.

32
00:02:45,781 --> 00:02:48,914
Which button you press matters too.

33
00:02:49,114 --> 00:02:57,228
If the button has a name, its name and value join the data, so the server can tell Save from Delete.

34
00:02:57,624 --> 00:03:00,606
Only the button you pressed is sent.

35
00:03:00,806 --> 00:03:03,707
A button can also overrule the form.

36
00:03:04,103 --> 00:03:14,992
formaction, formmethod, formenctype and formtarget replace the form's own attributes, for that button only.

37
00:03:15,192 --> 00:03:20,020
Our Preview button says formmethod="get".

38
00:03:20,103 --> 00:03:27,381
Press it, and the same fields go out as a GET, in the query string, to the same address.

39
00:03:27,591 --> 00:03:31,235
One form, two different requests.

40
00:03:31,435 --> 00:03:36,367
That formtarget points at the last part of the trip: where the answer goes.

41
00:03:36,509 --> 00:03:39,502
The form's target attribute picks the window.

42
00:03:39,643 --> 00:03:44,390
The default, _self, replaces the page you're on.

43
00:03:44,694 --> 00:03:47,397
_blank opens a new tab.

44
00:03:47,701 --> 00:03:52,958
Or name an iframe, and the answer lands inside it.

45
00:03:53,158 --> 00:04:02,978
Fun fact: before Ajax, a form aimed at a hidden iframe was how pages sent data without going anywhere.

46
00:04:03,678 --> 00:04:05,418
Now the body.

47
00:04:05,501 --> 00:04:14,381
When you press Send, the browser walks the form from top to bottom, in source order, collecting name and value pairs.

48
00:04:14,464 --> 00:04:18,235
This is called form serialization.

49
00:04:18,435 --> 00:04:21,626
The name comes from the field's name attribute.

50
00:04:21,686 --> 00:04:24,447
The value is whatever the field holds right now.

51
00:04:24,635 --> 00:04:28,696
A field with an id but no name isn't sent at all.

52
00:04:28,814 --> 00:04:29,927
Not empty.

53
00:04:29,987 --> 00:04:30,891
Absent.

54
00:04:31,171 --> 00:04:41,026
Name and id serve different purposes: the name is for the server, and the id is for labels, styles and scripts.

55
00:04:41,226 --> 00:04:47,006
Disabled fields are skipped too, and so are checkboxes nobody checked.

56
00:04:47,206 --> 00:04:49,306
But read-only fields are sent.

57
00:04:49,516 --> 00:04:51,395
So are hidden ones.

58
00:04:51,792 --> 00:04:56,330
The user can't change them, but they're still part of the form.

59
00:04:56,530 --> 00:05:01,300
That gives the server fullname, school, and source.

60
00:05:01,441 --> 00:05:09,415
The coupon was disabled, and the email field had no name, so the server never hears of either.

61
00:05:09,615 --> 00:05:22,407
Fun fact: hidden fields were one of the web's first ways to remember things from page to page, and they still carry the little facts a server needs back, like which item you're buying.

62
00:05:23,107 --> 00:05:25,416
The pairs can't go out as they are.

63
00:05:25,487 --> 00:05:30,083
A space or an ampersand inside a value would break the format.

64
00:05:30,154 --> 00:05:35,841
So the browser encodes them, by the rules the encoding type attribute names.

65
00:05:36,215 --> 00:05:38,918
Enc type, for short.

66
00:05:39,118 --> 00:05:44,956
The default is application/x-www-form-urlencoded.

67
00:05:45,190 --> 00:05:53,315
Pairs are joined with ampersands, spaces become plus signs, and anything risky becomes a percent sign and two hex digits.

68
00:05:53,642 --> 00:05:59,248
Joe O'Reilly becomes Joe+O%27Reilly.

69
00:05:59,448 --> 00:06:06,644
The browser adds a Content-Type header naming the encoding, so the server knows how to unpack the body.

70
00:06:06,948 --> 00:06:12,519
That header is the label from Three Things, now on a request.

71
00:06:12,719 --> 00:06:16,804
Now add a file input, and upload the cat photo.

72
00:06:16,945 --> 00:06:23,607
Forget to change the encoding, and the server receives the word cat.webp.

73
00:06:23,679 --> 00:06:25,349
Just the file's name.

74
00:06:25,374 --> 00:06:28,112
Not one byte of the cat.

75
00:06:28,312 --> 00:06:33,987
Files need enctype="multipart/form-data".

76
00:06:34,245 --> 00:06:41,348
The body becomes a stack of parts, one per field, divided by a boundary string the browser invents.

77
00:06:41,408 --> 00:06:47,698
Each part gets its own small headers, and the file's part carries the actual bytes.

78
00:06:47,899 --> 00:06:52,646
A third value, text/plain, exists too.

79
00:06:52,787 --> 00:06:56,314
It's not reliable to parse, so leave it alone.

80
00:06:56,711 --> 00:07:00,401
And notice what's missing: there is no JSON.

81
00:07:00,798 --> 00:07:04,314
An HTML form can't send it.

82
00:07:05,014 --> 00:07:09,296
Everything so far happens automatically, with no script.

83
00:07:09,379 --> 00:07:11,850
JavaScript can step in instead.

84
00:07:12,061 --> 00:07:17,899
Our code listens for the submit event, cancels it, and takes over the process.

85
00:07:18,099 --> 00:07:21,034
Now our script owns the request.

86
00:07:21,245 --> 00:07:30,986
It can still borrow the browser's walk: new FormData(form) collects exactly the same pairs, skipping and including the same fields.

87
00:07:30,986 --> 00:07:35,257
Or we can collect them ourselves, by hand.

88
00:07:35,457 --> 00:07:36,674
Careful, though.

89
00:07:36,885 --> 00:07:44,743
Hand that FormData to fetch, and it goes out as multipart, not as the form's default encoding.

90
00:07:45,047 --> 00:07:51,547
If your server expects the default, wrap it in URLSearchParams.

91
00:07:51,746 --> 00:08:05,966
We have full control of the process, so our script can build the body itself: JSON, with an application/json label, and any method it likes, PUT, PATCH or DELETE.

92
00:08:06,177 --> 00:08:08,334
The three parts are the same.

93
00:08:08,475 --> 00:08:12,247
The script just writes them instead of the browser.

94
00:08:12,447 --> 00:08:17,867
Fun fact: the form's limits became the web's security rule.

95
00:08:18,264 --> 00:08:27,376
A form could always post to any site, so a script may do the same, unasked, only if a form could have sent the request.

96
00:08:27,586 --> 00:08:34,945
Send JSON, or PUT, to another site, and the browser first asks that site for permission.

97
00:08:35,646 --> 00:08:38,907
Be careful: scripts can fail.

98
00:08:39,048 --> 00:08:43,957
They're blocked, slow to load, or broken by an error on the page.

99
00:08:44,168 --> 00:08:48,624
Then the browser's own form is all your user has.

100
00:08:48,824 --> 00:08:56,938
If the server endpoint only understands JSON, a form without JavaScript to enhance it is straight broken.

101
00:08:57,241 --> 00:09:04,217
Progressive enhancement means the HTML path works first, and the script makes it better.

102
00:09:04,417 --> 00:09:06,250
So design for both.

103
00:09:06,553 --> 00:09:11,637
Give the form a real action and a real method, and keep its fields named.

104
00:09:11,778 --> 00:09:14,284
Need a method HTML doesn't have?

105
00:09:14,680 --> 00:09:22,689
Many servers read a hidden field, often called \_method, and treat the POST as a PUT or a DELETE.

106
00:09:22,889 --> 00:09:34,602
Make sure your endpoint reads the Content-Type header and accepts both: form encoding when the HTML submits, JSON when the script does.

107
00:09:34,743 --> 00:09:40,093
That's a few lines on the server, and it keeps the form working for everyone.

108
00:09:40,293 --> 00:09:48,801
And the validation the form does, like required fields and patterns, is for the user's convenience, not your security.

109
00:09:49,105 --> 00:10:02,884
Anyone can skip the form and send the server any packet they like, so do security checks on the server and keep HTML and JavaScript validation for UX improvements.

110
00:10:03,584 --> 00:10:04,490
Try it.

111
00:10:04,490 --> 00:10:14,670
Point a form at https://cse134.site/api/echo and submit it.

112
00:10:14,915 --> 00:10:22,925
The answer should be your own request: the method, every header, and the raw body, exactly as the browser wrote it.

113
00:10:23,125 --> 00:10:35,406
Then switch the method to GET, add a disabled field, press a button with a formmethod, or upload a file without changing the encoding, and watch the request change.

114
00:10:35,606 --> 00:10:38,367
Method and action fill the first line.

115
00:10:38,392 --> 00:10:41,862
The host and the encoding type fill the headers.

116
00:10:42,166 --> 00:10:45,716
The form process fills the message body.

117
00:10:45,927 --> 00:10:50,442
A form, in effect, writes the HTTP packet for you.
