Cross-domain processing solutions
The Essence of Cross-Origin Issues
Cross-origin problems stem from the browser's same-origin policy restrictions. The same-origin policy requires that the protocol, domain, and port be identical for unrestricted communication. Requests from different origins are blocked by the browser, preventing the frontend from accessing response data. Common cross-origin scenarios include frontend-backend separation development, calling third-party APIs, and different subdomains.
JSONP Solution
JSONP leverages the fact that <script>
tags are not restricted by the same-origin policy to achieve cross-origin requests. The client defines a callback function, and the server returns JavaScript code that calls this function.
// Client-side code
function handleResponse(data) {
console.log('Received data:', data);
}
const script = document.createElement('script');
script.src = 'http://example.com/api?callback=handleResponse';
document.body.appendChild(script);
// Server response
handleResponse({data: "some data"});
Disadvantages:
- Only supports GET requests
- Poor security
- Difficult error handling
CORS Solution
CORS (Cross-Origin Resource Sharing) is a standardized cross-origin solution supported by modern browsers. The server declares allowed cross-origin requests by setting response headers.
Simple Requests
A request is considered simple if it meets the following conditions:
- Method is GET, HEAD, or POST
- Content-Type is text/plain, multipart/form-data, or application/x-www-form-urlencoded
// Server settings
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://client-domain.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
next();
});
Preflight Requests
Requests that do not meet the simple request conditions first send an OPTIONS preflight request.
// Server handling preflight requests
app.options('/api', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'http://client-domain.com');
res.setHeader('Access-Control-Allow-Methods', 'PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.status(204).end();
});
Credentialed Requests
Additional Access-Control-Allow-Credentials
header is required:
// Client-side
fetch('http://api.example.com', {
credentials: 'include'
});
// Server
res.setHeader('Access-Control-Allow-Credentials', 'true');
Proxy Server Solution
Requests are forwarded through a same-origin backend server to bypass browser restrictions. Node.js implementation example:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'http://target-server.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}));
app.listen(3000);
WebSocket Cross-Origin
The WebSocket protocol is not restricted by the same-origin policy, but the server must explicitly allow cross-origin connections:
// Client-side
const socket = new WebSocket('ws://server.example.com');
// Node.js server
const WebSocket = require('ws');
const wss = new WebSocket.Server({
port: 8080,
verifyClient: (info, done) => {
// Verify origin
done(info.origin === 'http://allowed-client.com');
}
});
postMessage Cross-Origin
Suitable for communication between iframes/windows:
// Sender
window.parent.postMessage('message content', 'http://target-origin.com');
// Receiver
window.addEventListener('message', (event) => {
if (event.origin !== 'http://trusted-origin.com') return;
console.log('Received message:', event.data);
});
Nginx Reverse Proxy
Request forwarding via Nginx configuration:
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass http://backend-server/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Practical Applications of Cross-Origin Resource Sharing
Handling Complex CORS Scenarios
// Express middleware
const corsOptions = {
origin: (origin, callback) => {
const allowedOrigins = ['https://domain1.com', 'https://domain2.com'];
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['X-Custom-Header'],
credentials: true,
maxAge: 86400
};
app.use(cors(corsOptions));
Handling Preflight Request Caching
app.options('*', cors(corsOptions)); // Global preflight request handling
Security Considerations
- Strictly limit
Access-Control-Allow-Origin
; avoid using*
- Implement CSRF protection for sensitive operations
- Validate the Origin header for all cross-origin requests
- Restrict allowed HTTP methods and headers
// Security example
app.use((req, res, next) => {
const allowedOrigins = new Set([
'https://www.myapp.com',
'https://api.myapp.com'
]);
const origin = req.headers.origin;
if (allowedOrigins.has(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Vary', 'Origin');
}
// Other security headers
res.setHeader('X-Content-Type-Options', 'nosniff');
next();
});
Performance Optimization Strategies
- Preflight request caching: Set
Access-Control-Max-Age
- Reduce unnecessary preflight requests: Use simple requests whenever possible
- CDN acceleration for cross-origin resources
- Compress cross-origin response data
// Set preflight request caching
app.use((req, res, next) => {
res.setHeader('Access-Control-Max-Age', '600');
next();
});
Common Issue Troubleshooting
- Check if response headers are correctly set
- Confirm if the request meets simple request conditions
- Verify if the server correctly handles the OPTIONS method
- Check browser console error messages
- Use curl to test API response headers
# Test using curl
curl -I -X OPTIONS http://api.example.com/resource
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:RESTful API设计
下一篇:负载均衡策略