CORS in AJAX Cross Origin Requests is an important AJAX topic because it appears in real projects, debugging sessions, and interviews. Learn the meaning first, then connect it to a small working example so the rule does not stay abstract.
For this page, focus on what problem CORS in AJAX Cross Origin Requests solves, where developers usually make mistakes, and how to verify the result. The audit note for this lesson was: under 650 content words; limited checklist/practice/mistake/FAQ notes .
A strong understanding of CORS in AJAX Cross Origin Requests should include syntax, behavior, one realistic use case, one failure case, and one quick way to check your work with tools or output.
CORS in AJAX Cross Origin Requests should be studied as a practical AJAX lesson, not as a label. Start by naming the input, the rule that changes the input, and the result a learner should be able to predict after reading the page.
In the ajax > cors page, the notes should connect the definition with a working scenario, a mistake that beginners actually make, and the exact check that proves the fix. That makes the topic useful for coding, debugging, and interview revision.
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that controls how web pages can request resources from a different origin (domain, protocol, or port) than the one that served the page.
The Same-Origin Policy (SOP) is the underlying rule: by default, a script on https://app.example.com cannot make AJAX requests to https://api.other.com. CORS is the standard way to relax this restriction in a controlled manner.
An "origin" is defined as the combination of: protocol + hostname + port. Any difference makes it cross-origin.
| Header | Direction | Purpose |
|---|---|---|
| Access-Control-Allow-Origin | Response | Which origins are allowed (* or specific origin) |
| Access-Control-Allow-Methods | Response | Allowed HTTP methods (GET, POST, PUT, DELETE) |
| Access-Control-Allow-Headers | Response | Allowed request headers |
| Access-Control-Allow-Credentials | Response | Whether cookies/auth headers are allowed |
| Access-Control-Max-Age | Response | How long to cache preflight results (seconds) |
| Origin | Request | The origin of the requesting page |
<?php
// api.php - Enable CORS headers
// Allow a specific origin (recommended over *)
$allowedOrigins = ['https://app.example.com', 'https://www.example.com'];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
} else {
// Or allow all origins (less secure, fine for public APIs)
// header('Access-Control-Allow-Origin: *');
}
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
header('Access-Control-Allow-Credentials: true'); // required for cookies/auth
header('Access-Control-Max-Age: 86400'); // cache preflight for 24 hours
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204); // No Content
exit;
}
// Continue with normal request handling...
header('Content-Type: application/json');
echo json_encode(['message' => 'CORS-enabled response']);
?>
Simple requests do not trigger a preflight. They must use GET, HEAD, or POST with only safe headers (Content-Type: application/x-www-form-urlencoded, multipart/form-data, or text/plain).
Preflight requests are automatically sent by the browser as an HTTP OPTIONS request before the actual request. They occur when the request uses a non-simple method (PUT, DELETE, PATCH), a non-simple Content-Type (like application/json), or custom headers (like Authorization).
// npm install cors
const express = require('express');
const cors = require('cors');
const app = express();
// Option 1: Allow all origins (public API)
app.use(cors());
// Option 2: Allow specific origins with full config
app.use(cors({
origin: ['https://app.example.com', 'https://www.example.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true, // allow cookies and auth headers
maxAge: 86400 // cache preflight for 24 hours
}));
// Option 3: Dynamic origin validation
app.use(cors({
origin: function (origin, callback) {
const whitelist = ['https://app.example.com'];
if (!origin || whitelist.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS-enabled response' });
});
app.listen(3000);
// ---- PROXY APPROACH (recommended modern solution) ----
// Your own server proxies the request to the third-party API
// Client -> Your Server -> Third-Party API -> Your Server -> Client
// No CORS issue because the server-to-server call is not browser-restricted
// Client code (calls your own server)
fetch('/proxy/weather?city=London')
.then(res => res.json())
.then(data => console.log(data));
// Your server (proxy.php or Express route) forwards to the real API:
// $response = file_get_contents("https://api.weather.com/v1/city=London&key=SECRET");
// echo $response;
// ---- JSONP (legacy - only GET, avoid in new code) ----
// JSONP works by injecting a <script> tag - not a real AJAX request
// The server wraps the response in a callback function call
function handleWeatherData(data) {
console.log('Temperature:', data.temp);
}
// Dynamically create a script tag
const script = document.createElement('script');
script.src = 'https://api.example.com/weather?city=London&callback=handleWeatherData';
document.head.appendChild(script);
// Server responds with: handleWeatherData({"temp": 22, "city": "London"})
// The browser executes it as JavaScript, calling our function
// NOTE: JSONP is a security risk and only supports GET.
// Use CORS or a proxy instead.
When studying CORS in AJAX Cross Origin Requests, separate three things: the concept, the syntax, and the situation where it is useful. This prevents the lesson from becoming a list of commands with no practical meaning.
In AJAX, CORS in AJAX Cross Origin Requests becomes easier when you build a tiny example first, then increase complexity. Add one realistic input, one invalid or boundary input, and one explanation of why the result changes.
const state = { topic: "CORS in AJAX Cross Origin Requests", ready: true };
if (state.ready) {
console.log(state.topic + ": render or run the normal path");
}
const response = null;
const message = response?.message ?? "CORS in AJAX Cross Origin Requests: show a clear fallback";
console.log(message);
Memorizing CORS in AJAX Cross Origin Requests without the situation where it is useful.
Connect CORS in AJAX Cross Origin Requests to a concrete AJAX task.
Testing CORS in AJAX Cross Origin Requests only with the perfect input.
Include empty, missing, duplicate, incompatible, or failed cases when relevant.
Changing code before reading the visible symptom or error message.
Inspect the output, state, configuration, or stack trace connected to CORS in AJAX Cross Origin Requests.
Memorizing CORS in AJAX Cross Origin Requests without the situation where it is useful.
Connect CORS in AJAX Cross Origin Requests to a concrete AJAX task.
The common mistake is memorizing syntax without understanding when the behavior changes or fails.
Remember the problem it solves in AJAX, then attach the syntax or steps to that problem.
You can predict the result of a small example, explain a failure case, and choose it over a nearby alternative for a clear reason.
They often copy the syntax but skip the state, input, dependency, selector, route, type, or configuration that controls the behavior.
Explore 500+ free tutorials across 20+ languages and frameworks.