Keywords: CORS | Preflight Request | Cross-Origin Resource Sharing | Access-Control-Allow-Origin | AngularJS
Abstract: This article provides an in-depth analysis of common CORS preflight request errors in browser cross-origin requests, focusing on the 'Response to preflight request doesn't pass access control check: No Access-Control-Allow-Origin header is present' error. The paper systematically introduces four main solutions: browser CORS disabling, plugin usage, proxy server configuration, and server-side CORS setup, with practical code examples illustrating each method's implementation details. Through thorough technical analysis and practical guidance, it helps developers comprehensively understand and resolve cross-origin resource access issues.
Fundamental Causes of CORS Preflight Request Errors
Cross-Origin Resource Sharing (CORS) is a common security mechanism in modern web development. When browsers detect cross-origin requests, they first send preflight requests to verify whether the server permits such cross-origin access. Preflight requests use the OPTIONS method and include headers such as Origin, Access-Control-Request-Method, and Access-Control-Request-Headers.
In your specific case, the frontend application runs on http://localhost while attempting to access a REST API located at http://server.apiurl.com:8000. This cross-origin request (different protocol, domain, or port) triggers the browser's CORS checking mechanism. The server fails to return the correct Access-Control-Allow-Origin header, causing the preflight request to fail and the browser to block the actual request execution.
Analysis of Cross-Origin Requests in AngularJS ngResource
Let's deeply analyze the code example you provided. When using the $resource service in AngularJS applications to create RESTful API clients, special attention must be paid to cross-origin configuration:
// Factory service definition
angular.module('socialMarkt').factory('loginService', ['$resource', function($resource) {
var apiAddress = "http://server.apiurl.com:8000/s/login/";
return $resource(apiAddress, {
login: "facebook",
access_token: "@access_token",
facebook_id: "@facebook_id"
}, {
getUser: {
method: 'POST',
// CORS-related configuration can be added
headers: {
'Content-Type': 'application/json'
}
}
});
}]);
// Usage in controller
loginService.getUser(JSON.stringify(fbObj)),
function(data) {
console.log(data);
},
function(result) {
console.error('Error', result.status);
}
When executing POST requests, browsers automatically send preflight requests. Since the server is not properly configured with CORS headers, the preflight fails and returns a 405 status code, indicating that the server does not support the OPTIONS method.
Solution One: Browser-Side CORS Disabling
For development environments, temporarily disabling the browser's CORS check is the quickest solution. In Chrome browser, this can be achieved through:
# Launch Chrome with security policies disabled
chrome.exe --disable-web-security --user-data-dir=/tmp/chrome-dev
This method should only be used in development and testing environments and never in production. It completely bypasses the browser's same-origin policy and may introduce security risks.
Solution Two: Browser Plugin Usage
Installing specialized CORS plugins can provide more convenient cross-origin access support. For example, the "Allow CORS: Access-Control-Allow-Origin" plugin in Chrome Web Store:
// The plugin automatically adds CORS headers to all requests
// Enables cross-origin access without code modification
This approach is suitable for frontend developers during local debugging but is similarly not recommended for production environments that rely on browser plugins.
Solution Three: Proxy Server Configuration
Using a proxy server is one of the most recommended solutions. By configuring reverse proxy servers like nginx, cross-origin requests can be converted to same-origin requests:
# nginx configuration example
server {
listen 8000;
server_name localhost;
location /api/ {
proxy_pass http://server.apiurl.com:8000/s/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Add CORS headers
add_header Access-Control-Allow-Origin '*' always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'Origin, Content-Type, Accept, Authorization' always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'Origin, Content-Type, Accept, Authorization';
return 204;
}
}
}
After configuration, the frontend code can be modified to access the local proxy:
// Modify API address to local proxy
var apiAddress = "http://localhost:8000/api/login/";
Solution Four: Server-Side CORS Configuration
The most fundamental solution is to properly configure CORS on the server side. Configuration methods vary depending on different server technologies:
Node.js Express Server Configuration
const express = require('express');
const cors = require('cors');
const app = express();
// Use cors middleware
app.use(cors({
origin: 'http://localhost',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
credentials: true
}));
// Manually handle OPTIONS requests
app.options('*', cors());
// Or manually set CORS headers
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
next();
});
PHP Server Configuration
// Add CORS headers at the beginning of PHP script
header('Access-Control-Allow-Origin: http://localhost');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token, Authorization');
// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit();
}
Detailed Mechanism of Preflight Requests
Preflight requests are a crucial component of the CORS mechanism, automatically triggered in the following situations:
- Using HTTP methods other than GET, HEAD, or POST
- Setting custom request headers
- Content-Type is not application/x-www-form-urlencoded, multipart/form-data, or text/plain
In your case, since POST method is used and may include custom headers, the browser automatically sent an OPTIONS preflight request. The server needs to properly handle these OPTIONS requests and return appropriate CORS headers.
Analysis and Resolution of Error 405
Error 405 "Method Not Allowed" indicates that the server does not support the OPTIONS method. This typically occurs because:
- Server routes are not configured to handle OPTIONS method
- Web server configuration (like Apache, Nginx) restricts OPTIONS method
- Application framework does not properly set CORS middleware
Solutions include adding OPTIONS method handling in server routes or configuring the web server to allow OPTIONS requests.
Security Considerations and Best Practices
When configuring CORS, security should be the primary consideration:
- Avoid using wildcard
*, explicitly specify allowed origins - Restrict allowed HTTP methods and headers in production environments
- Consider security risks when using credential mode
- Regularly review and update CORS configurations
Recommended CORS configuration pattern:
// Secure CORS configuration example
const allowedOrigins = ['http://localhost', 'https://myapp.com'];
app.use(cors({
origin: function(origin, callback) {
// Allow requests without origin (like mobile applications)
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) === -1) {
return callback(new Error('CORS policy violation'), false);
}
return callback(null, true);
},
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
maxAge: 86400 // Preflight request cache time
}));
Summary and Recommendations
CORS preflight request errors are common issues in web development. Understanding their mechanisms is crucial for building modern web applications. Based on different development stages and requirements, appropriate solutions can be selected:
- Development stage: Use browser plugins or temporarily disable CORS
- Testing environment: Configure proxy servers
- Production environment: Properly configure CORS on the server side
Through the analysis and examples in this article, you should be able to comprehensively understand the causes of CORS preflight request errors and master multiple effective solutions. In actual projects, prioritizing server-side CORS configuration is recommended, as it complies with web standards while providing optimal security and user experience.