Understanding Cross-Origin Requests and Frontend Solutions for CORS
This article explains the concept of cross‑origin requests, the same‑origin policy that restricts them, and presents three practical frontend solutions—JSONP, a server‑side proxy using Nest.js, and Webpack dev‑server proxy configuration—along with code examples and security considerations.
What Is Cross-Origin
When a web page tries to access resources from a different domain (e.g., Ajax requests or iframes), the browser enforces the same‑origin policy , which can block the request and cause errors such as No ‘Access-Control-Allow-Origin’ header is present on the requesting resource .
What Is the Same‑Origin Policy
The same origin requires that the protocol, domain name, and port are identical for two URLs. For example, a request from http://domain1.com/api to http://domain1.com is allowed, while a request to http://domain2.com/api is blocked by the browser.
Why Browsers Enforce Cross‑Origin Restrictions
These restrictions protect users from malicious sites that could forge requests and steal sensitive information such as cookies, usernames, or passwords. An attacker could embed JavaScript on a malicious site that sends a cross‑origin request to a victim’s logged‑in site and exfiltrate data.
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.domain2.com/user-info", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
alert(xhr.responseText);
// upload the stolen data to the attacker’s server
}
}
xhr.send();Elegant Frontend Solutions
The quickest fix is to ask the backend to enable CORS , but there are three common frontend approaches:
JSONP
Proxy server
Webpack dev‑server proxy
JSONP
JSONP uses a <script> tag to perform a GET request, bypassing the same‑origin policy. The server wraps the JSON data in a callback function.
var data = {
"name": "Alice",
"age": 18
};
var callback = req.query.callback; // get callback name
res.send(callback + '(' + JSON.stringify(data) + ')');Client side:
function handleResponse(data) {
console.log(data);
}
var script = document.createElement('script');
script.src = 'http://www.domain2.com/getData?callback=handleResponse';
document.head.appendChild(script);JSONP works in all browsers but only supports GET requests and only returns JSON.
Proxy Server
A local server forwards requests to the target domain, avoiding the browser’s same‑origin check. Example using Nest.js:
import { Controller, Post, Req, Res, Body } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Request, Response } from 'express';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Controller()
export class AppController {
constructor(private readonly httpService: HttpService) {}
@Post('/api')
proxy(@Req() request: Request, @Res() response: Response, @Body() data: any): Observable
{
const url = request.query.url as string;
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
return this.httpService.post(url, data, { headers }).pipe(
map(res => {
response.send(res.data);
}),
);
}
}Webpack Dev‑Server Proxy
For projects using Webpack, add a proxy configuration in webpack.config.js :
// webpack.config.js
module.exports = {
// ...
devServer: {
proxy: {
'/api': {
target: 'http://www.domain2.com', // target URL
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
}
}Then request /api/data from the frontend; the dev server forwards it to the target domain.
axios.get('/api/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});Common Pitfalls
Remember that requests from a frontend server to another server also need CORS handling if the ports differ.
Conclusion
If you found this guide useful, feel free to like, bookmark, or share it.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.