<a ref="https://www.cuhk.edu.hk/">CUHK</a>
<img src="../ierg/cuhk.png" />
<link href="styles.css" rel="stylesheet" type="text/css" /> //Place in head or body?
<li><a href="#b">About Us<a></li>
*{ color: red; }
#a > #c{ color: black; }
p.c{ color: blue; }
p#c{ color: green; }
Hello
World
Click
...
for (var i=0; i<4; i++){
const item = document.createElement("li")
item.innerHTML = "Product" + i
item.onclick = () => {alert(i)} //Suppose to alert(1) for Product 1
document.getElementById("list").appendChild(item)
}
req.txt | nc www.ie.cuhk.edu.hk 80
""" context of req.txt
GET / HTTP/1.1
Host: www.ie.cuhk.edu.hk
Connection: close
"""
//ensure newline is \r\n instead of \n; and the newline after Connection: close
$ nc www.ie.cuhk.edu.hk 80 (assume we send the HTTP request)
GET / HTTP/1.1
Host: www.ie.cuhk.edu.hk
HTTP/1.1 301 Moved Permanently
Date: Wed, 03 Feb 2021 18:11:26 GMT
Server: Apache
Location: https://www.ie.cuhk.edu.hk/
Content-Length: 235
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a
href="https://www.ie.cuhk.edu.hk/">here</a>.</p>
</body></html>
GET /testing?q=abc HTTP/1.1
Host: course.ie.cuhk.edu.hk
POST /testing?q=abc HTTP/1.1
Host: course.ie.cuhk.edu.hk
Content-Length: 105
Content-Type: application/x-www-form-urlencoded
name=World&gender=M&email=xxx%40ie.cuhk.edu.hk&address=SHB%2C+CUHK%2C+NT®ion=NT&action=updInfoGET,
POST,
PUT,
HEAD,
DELETE,
TRACE,
OPTIONS,
CONNECT, etc...HTTP/1.1 200 OK
Date: Mon, 26 Jan 2015 17:00:28 GMT
Content-Length: 413
Content-Type: text/html
<HTML>...</HTML>
<form> tag that
comprises different form controls, e.g.,
<input>, <select>, see a typical example below:
<fieldset>
<legend>Personal Information</legend>
<form method="POST" action="incl/process.php"><ul><li>
<label>Name*</label>
<div><input type="text" name="name" required /></div>
</li><li>
<label>Gender*</label>
<div><input required type="radio" name="gender" value="M" /> M
<input type="radio" name="gender" value="F" /> F</div>
</li><li>
<label>Email*</label>
<div><input type="email" name="email" required placeholder="john@example.com" /></div>
</li><li>
<label>Address*</label>
<div><textarea name="address" required></textarea></div>
</li><li>
<label>Region*</label>
<div><select required name="region">
<option value="">Choose</option>
<option value="HK">HK</option>
<option value="KL">KL</option>
<option value="NT">NT</select>
</div>
</li>
</ul>
<input type="hidden" name="action" value="updInfo" />
<input type="submit" value="Send" /><span> * denotes a required field.</span>
</form>
</fieldset>
<form> takes at least two attributes:
<form method="POST" action="process.php">
<!-- included here are some form controls -->
</form>method="POST" or method="GET"
(default: GET)
action="process.php" (default: the current URL)
onsubmit="return false" is optional
onsubmit is triggered when the submit button is clicked.return false; prevents default behaviour, stop propagation (bubble-up), and callbacksenctype="multipart/form-data" is optional
application/x-www-form-urlencodedd<input type="file"/> is used for file upload <!-- <label> is to focus on a field when clicked -->
<label for="field1">Field 1: </label>
<input type="text" name="param1" id="field1" />
First Name: <input type="text" name="firstname" value="World"/>
Password: <input type="password" name="name" value="abc"/>
Hidden? <input type="hidden" name="action" value="updateData"/>
<input type="radio" name="sex" value="M" checked="true" /> Male
<input type="radio" name="sex" value="F" /> Female
<input type="checkbox" name="item[]" value="A" checked="true"/> A
<input type="checkbox" name="item[]" value="B" /> B
Which OS do you like:
<select name="OS">
<option name="1">iOS</option>
<option name="2" selected="true">Android</option>
</select>
Description:
<textarea name="desc" > text to be displayed </textarea>
Photos: <input type="file" name="pics" />
<input type="submit" value="Go" />
<input type="image" src="pics/go.gif" />
<form>Email:*
<input type="email" name="email" required />
<input type="date" />
</form>
<style>:valid{border:1px solid #0F0}
:invalid{border:1px solid #F00}</style>
<form>URL: <input type="URL" name="url" /></form>
<form><input type="search" name="q" placeholder="Search..." /></form>
<form>Amount: $
<input type="text" name="amount" pattern="^[\d,.]+$" />
</form>
:valid, :invalid, :required and :optional
^[\d\.]+$
^[\w\-, ]+$
^[\w\-\/][\w\'\-\/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$
The regular expression for email address is readily available on Web.
(You need to first know what constitutes a valid email address to
write this regex.)
IMPORTANT: Consult credible websites for
reusable rigorous patterns!!
^[\d\.]+$[+-]?([0-9]*[\.])?[0-9]+<form id="loginForm" method="POST">
Email: <input type="email" name="em" /><br/>
Password: <input type="password" name="pw" /><br/>
<input type="submit" value="Login" />
</form>
Note: Unsupported type will fallback to an ordinary textfield
<form id="loginForm" method="POST">
Email: <input type="email" name="em" title="valid email" required
pattern="^[\w\-\/][\w\'\-\/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$" /><br/>
Password: <input type="password" name="pw"
title="valid password" required /><br/>
<input type="submit" value="Login" />
</form>
Note:
<form id="loginForm" method="POST">
Email: <input type="email" name="em" title="valid email" required pattern="^[\w\-\/][\w\'\-\/\.]*@[\w\-]+(\.[\w\-]+)*(\.[\w]{2,6})$" /><br/>
Password: <input type="password" name="pw" title="valid password" required /><br/>
<input type="submit" value="Login" />
</form>
<script type="text/javascript">
var loginForm = document.getElementById('loginForm');
// Do this only if the HTML5 Form Validation is absent
if (!loginForm.checkValidity || loginForm.noValidate)
// to listen on the submit event of "loginForm"
loginForm.onsubmit = function(){
// a private function for displayError
function displayErr(el,msg){alert('FieldError: ' + msg);el.focus();return false}
// looping over the array of elements contained in the form
for (var i = 0, p, el, els = this.elements; el = els[i]; i++) {
// validate empty field if required attribute is present
if (el.hasAttribute('required') && el.value == '')
return displayErr(el, el.title + ' is required');
// validate pattern if pattern attribute is present
if ((p = el.getAttribute('pattern')) && !new RegExp(p).test(el.value))
return displayErr(el, 'in' + el.title);
}
// If false is returned above, the form submission will be canceled;
// If false is NOT returned, the form will submit accordingly
}
</script>
Note: POST Parameters can be accessed only by server but not JS. Hence, nothing is shown here after submission. Firebug can show what was already sent.
novalidate attribute:Note: Need to perform compatibility tests? try some online services or install those in Virtual Machines
radio and checkbox
for (var i = 0, p, el, els = this.elements; el = els[i]; i++) {
// validate empty field, radio and checkboxes
if (el.hasAttribute('required')) {
if (el.type == 'radio') {
if (lastEl && lastEl == el.name) continue;
for (var j = 0, chk = false, lastEl = el.name, choices = this[lastEl],
choice; choice = choices[j]; j++)
if (choice.checked) {chk = true; break;}
if (!chk) return displayErr(el, 'choose a ' + el.title);
continue;
} else if ((el.type == 'checkbox' && !el.checked) || el.value == '')
return displayErr(el, el.title + ' is required');
}
if ((p = el.getAttribute('pattern')) && !new RegExp(p).test(el.value))
return displayErr(el, 'in' + el.title);
}
Code Demo. Reading: MDN Client-side form validation
submit event, where one can validate before a form submission<form method="POST" id="buildAutoPostReq"><!-- Some hidden fields here --></form>
<script type="text/javascript">document.forms[0].submit();</script><input type="image"> like to do this for images: When an image is clicked, Form.submit() will be finally called if a form is properly validatedsubmit event is fired. Without code analysis, difficult to know whether a submission has actually occurredXMLHttpRequest API, study it before using it to submit form dataXMLHttpRequest API
false in the submit event
As opposed to asynchronous calls, synchronous calls are blocking (hangs) until the server returns, i.e., less efficient.
submit eventPOST request to send over AJAXXMLHttpRequest// e.g., to call, myLib.ajax({url:'process.php?q=hello',success:function(m){alert(m)}});
myLib.ajax = function(opt) { opt = opt || {};
var xhr = (window.XMLHttpRequest) // Usu. ?/|| is for compatibility
? new XMLHttpRequest() // IE7+, Firefox1+, Chrome1+, etc
: new ActiveXObject("Microsoft.XMLHTTP"), // IE 6
async = opt.async || true,
success = opt.success || null, error = opt.error || function(){/*displayErr()*/};
// pass three parameters, otherwise the default ones, to xhr.open()
xhr.open(opt.method || 'GET', opt.url || '', async); // 3rd param true = async
if (opt.method == 'POST')
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Asyhronous Call requires a callback function listening on readystatechange
if (async)
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) { // 4 is "more ready" than 3 or 2
var status = xhr.status;
if ((status >= 200 && status < 300) || status == 304 || status == 1223)
success && success.call(xhr, xhr.responseText); // raw content of the response
else if (status < 200 || status >= 400)
error.call(xhr);
}
};
xhr.onerror = function(){error.call(xhr)};
// POST parameters encoded as opt.data is passed here to xhr.send()
xhr.send(opt.data || null); // return RHS if LHS is any false value [use && for null/undefined]
// Synchronous Call blocks UI and returns result immediately after xhr.send()
!async && success && success.call(xhr, xhr.responseText);
};
myLib.formData = function(form) {
// private variable for storing parameters
this.data = [];
for (var i = 0, j = 0, name, el, els = form.elements; el = els[i]; i++) {
// skip those useless elements
if (el.disabled || el.name == ''
|| ((el.type == 'radio' || el.type == 'checkbox') && !el.checked))
continue;
// add those useful to the data array
this.append(el.name, el.value);
}
};
// public methods of myLib.formData
myLib.formData.prototype = {
// output the required final POST parameters, e.g., a=1&b=2&c=3
toString: function(){
return this.data.join('&');
},
// encode the data with the built-in function encodeURIComponent
append: function(key, val){
this.data.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
}
};
myLib.ajax({data:""})myLib.submitOverAJAX = function(form, opt) {
var formData = new myLib.formData(form);
formData.append('rnd', new Date().getTime());
opt = opt || {};
opt.url = opt.url || form.getAttribute('action');
opt.method = opt.method || 'POST';
opt.data = formData.toString();
opt.success = opt.success || function(msg){alert(msg)};
myLib.ajax(opt);
};function el(A) {return document.getElementById(A)};
var loginForm = el('loginForm');
loginForm.onsubmit = function(){
// submit the form over AJAX if it is properly validated
myLib.validate(this) && myLib.submitOverAJAX(this, {success:function(msg){
el('result').innerHTML = 'Echo from Server: $_POST = ' + msg.escapeHTML();
}});
return false; // always return false to cancel the default submission
}
When all the functions (incl. myLib.validate()) are built in a single library
const form = document.querySelector("#userinfo");
async function sendData() {
// Associate the FormData object with the form element
const formData = new FormData(form);
try {
const response = await fetch("https://example.org/post", {
method: "POST",
// Set the FormData instance as the request body
body: formData,
});
console.log(await response.json());
} catch (e) {
console.error(e);
}
}
// Take over form submission
form.addEventListener("submit", (event) => {
event.preventDefault();
sendData();
});