HTTP Deep dive


Headers
HTTP headers are key-value pairs sent between a client
(like a web browser) and a server
in an HTTP request or response. They convey metadata about the request or response, such as content type, auth information etc.
Common headers
Authorization (Sends the user auth information)
Content-Type - Type of information client is sending (json, binary etc)
Referer - Which URL is this request coming from
Request headers
The headers the client
sends out in the request are known as request headers
Response headers
The headers that the server
responds with are known as the response headers.
Fetch API
There are 2 high level
ways a browser can send requests to an HTTP server:
From the browser URL (Default GET request):
- When you type a URL into the browser’s address bar and press Enter, the browser sends an HTTP GET request to the server. This request is used to retrieve resources like HTML pages, images, or other content.
From an HTML form or JavaScript (Various request types):
HTML Forms: When a user submits a form on a webpage, the browser sends an HTTP request based on the form’s
method
attribute, which can beGET
orPOST
. Forms withmethod="POST"
typically send data to the server for processing (e.g., form submissions).JavaScript (Fetch API): JavaScript running in the browser can make HTTP requests to a server using APIs the
fetch
API. These requests can be of various types (GET
,POST
,PUT
,DELETE
, etc.) and are commonly used for asynchronous data retrieval and manipulation (e.g., AJAX requests).Fetch request examples
Server to send the request to - https://jsonplaceholder.typicode.com/posts/1 (GET request)
<!DOCTYPE html> <html> <body> <div id="posts"></div> <script> async function fetchPosts() { const res = await fetch("https://jsonplaceholder.typicode.com/posts/1"); const json = await res.json(); document.getElementById("posts").innerHTML = json.title; } fetchPosts(); </script> </body> </html>
Using axios (external library)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.6/axios.min.js"></script>
</head>
<body>
<div id="posts"></div>
<script>
async function fetchPosts() {
const res = await axios.get("https://jsonplaceholder.typicode.com/posts/1");
document.getElementById("posts").innerHTML = res.data.title;
}
fetchPosts();
</script>
</body>
</html>
Create an HTTP Server
It should have 4 routes
Inputs given at the end after ?
are known as query parameters (usually used in GET requests)
The way to get them in an HTTP route is by extracting them from the req
argument (req.query.a , req.query.b)
Steps to follow
Initialize node project
npm init -y
Install dependencies
npm install express
Create an empty index.js
touch index.js
Write the code to create 4 endpoints
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
});
app.get("/multiply", function(req, res) {
});
app.get("/divide", function(req, res) {
});
app.get("/subtract", function(req, res) {
});
app.listen(3000);
Fill in the handler body
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.get("/multiply", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a * b
})
});
app.get("/divide", function(req, res) {
const a = req.query.a;
const b = req.query.b;
res.json({
ans: a / b
})
});
app.get("/subtract", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a - b
})
});
app.listen(3000);
Test it in the browser
Middlewares
In Express.js, middleware refers to functions that have access to the request object (req
), response object (res
), and the next
function in the application's request-response cycle. Middleware functions can perform a variety of tasks, such as
Modifying the request or response objects.
Ending the request-response cycle.
Calling the next middleware function in the stack.
Modifying the request
const express = require("express");
const app = express();
app.use(function(req, res, next) {
req.name = "palyer1"
next();
})
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Ending the request/response cycle
const express = require("express");
const app = express();
app.use(function(req, res, next) {
res.json({
message: "You are not allowed"
})
})
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Calling the next middleware function in the stack
const express = require("express");
const app = express();
app.use(function(req, res, next) {
console.log("request received");
next();
})
app.get("/sum", function(req, res) {
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
Route specific middlewares
Route-specific middleware in Express.js refers to middleware functions that are applied only to specific routes or route groups, rather than being used globally across the entire application
const express = require('express');
const app = express();
// Middleware function
function logRequest(req, res, next) {
console.log(`Request made to: ${req.url}`);
next();
}
// Apply middleware to a specific route
app.get('/special', logRequest, (req, res) => {
res.send('This route uses route-specific middleware!');
});
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Commonly used middlewares
Through your journey of writing express servers
, you’ll find some commonly available (on npm) middlewares that you might want to use
1. express.json
The express.json()
middleware is a built-in middleware function in Express.js used to parse incoming request bodies that are formatted as JSON. This middleware is essential for handling JSON payloads sent by clients in POST or PUT requests.
const express = require('express');
const app = express();
// Use express.json() middleware to parse JSON bodies
app.use(express.json());
// Define a POST route to handle JSON data
app.post('/data', (req, res) => {
// Access the parsed JSON data from req.body
const data = req.body;
console.log('Received data:', data);
// Send a response
res.send('Data received');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
cors - Cross origin resource sharing
Cross-Origin Resource Sharing (CORS) is a security feature implemented by web browsers that controls how resources on a web server can be requested from another domain. It's a crucial mechanism for managing cross-origin
requests and ensuring secure interactions between different origins
on the web.
Cross origin request from the browser
Same request from Postman
Real world example
Create an HTTP Server
- Create an HTTP Server
const express = require("express");
const app = express();
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.listen(3000);
Create an index.html file (public/index.html)
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.6/axios.min.js"></script>
</head>
<body>
<div id="posts"></div>
<script>
async function sendRequest() {
const res = await axios.get("http://localhost:3000/sum?a=1&b=2");
}
sendRequest();
</script>
</body>
</html>
Serve the HTML File on a different port
cd public
npx serve
You will notice the cross origin request fails
Add cors as a dependency
npm i cors
Use the cors middleware
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
app.get("/sum", function(req, res) {
console.log(req.name);
const a = parseInt(req.query.a);
const b = parseInt(req.query.b);
res.json({
ans: a + b
})
});
app.listen(3000);
You dont need cors
if the frontend and backend are on the same domain
Try serving the frontend on the same domain
const express = require("express"); const app = express(); app.get("/sum", function(req, res) { console.log(req.name); const a = parseInt(req.query.a); const b = parseInt(req.query.b); res.json({ ans: a + b }) }); app.get("/", function(req, res) { res.sendFile(__dirname + "/public/index.html"); }); app.listen(3000);
Go to localhost:3000 , notice that the underlying request doesnt fail with cors
(even though we don’t have the cors middleware)
Subscribe to my newsletter
Read articles from Chauhan Balaji directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Chauhan Balaji
Chauhan Balaji
Computer Science student | Future Software Engineer | Code. Learn. Build. Repeat.