STM32低功耗模式怎么选?一张图看懂STOP0/1/2区别,附CubeIDE配置实例(STM32L4系列)
2026/5/12 15:40:21
跨域请求问题是现代Web开发中常见的通信障碍,尤其在前后端分离架构下尤为突出。当浏览器发起的HTTP请求的目标资源与当前页面所在域名不同时,即构成“跨域”。由于PHP通常作为后端服务运行在特定域名或端口上,前端JavaScript通过Ajax调用该服务时,若协议、域名或端口任一不同,浏览器便会基于同源策略(Same-Origin Policy)阻止该请求,除非服务器明确允许。
同源策略是浏览器为保障用户信息安全而实施的核心安全模型。它限制了一个源加载的文档或脚本如何与另一个源的资源进行交互。只有当两个URL的协议、域名和端口完全一致时,才被视为同源。
http://example.com与https://example.comapi.example.com与web.example.comlocalhost:8080与localhost:3000为解决合法跨域需求,W3C制定了CORS(Cross-Origin Resource Sharing)规范。服务器可通过设置特定的响应头告知浏览器允许来自指定源的请求。
<?php // 允许任意域名访问(生产环境应限制具体域名) header("Access-Control-Allow-Origin: *"); // 允许的请求方法 header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许携带的请求头 header("Access-Control-Allow-Headers: Content-Type, Authorization"); // 预检请求的缓存时间(秒) header("Access-Control-Max-Age: 3600"); // 处理预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; } ?>| 响应头 | 作用说明 |
|---|---|
| Access-Control-Allow-Origin | 指定允许访问的源 |
| Access-Control-Allow-Methods | 定义允许的HTTP方法 |
| Access-Control-Allow-Headers | 声明允许的请求头字段 |
Access-Control-Allow-Origin明确允许该源访问资源。OPTIONS /data HTTP/1.1 Host: api.example.com Origin: https://site-a.com Access-Control-Request-Method: PUT此预检请求告知服务器实际请求的方法和头部,服务器返回是否允许的策略。Access-Control-Allow-Origin:指定允许访问的源Access-Control-Allow-Credentials:是否接受凭证信息Access-Control-Max-Age:预检结果缓存时间(秒)header("Access-Control-Allow-Origin: https://example.com"); header("Access-Control-Allow-Methods: GET, POST"); header("Access-Control-Allow-Headers: Content-Type");上述代码允许指定来源发起常规请求,Allow-Headers声明支持的头部字段。if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header("Access-Control-Allow-Origin: https://example.com"); header("Access-Control-Allow-Methods: PUT, DELETE"); header("Access-Control-Allow-Headers: Authorization, Content-Type"); header("Access-Control-Max-Age: 86400"); // 缓存预检结果1天 exit; }通过Max-Age减少重复预检,提升性能。实际业务请求将在预检通过后发送。const allowedOrigins = ['https://site-a.com', 'https://site-b.com']; app.use((req, res, next) => { const origin = req.headers.origin; if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); } res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); next(); });上述代码逻辑首先定义合法源列表,中间件拦截每个请求,验证 `Origin` 是否在许可范围内。若匹配,则设置对应响应头,避免通配符 `*` 与凭证请求冲突。| 方式 | 安全性 | 灵活性 |
|---|---|---|
| 通配符 * | 低 | 高 |
| 静态单域名 | 中 | 低 |
| 动态白名单 | 高 | 高 |
app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'https://example.com'); res.header('Access-Control-Allow-Headers', 'Content-Type, X-Request-ID, Authorization'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); if (req.method === 'OPTIONS') { res.sendStatus(200); // 快速响应预检 } else { next(); } });上述代码拦截所有请求,检查是否为预检请求。若是,则返回状态码200,告知浏览器允许后续操作;否则继续处理业务逻辑。关键在于精确配置允许的头部字段,避免因通配符 `*` 导致凭证请求失败。Access-Control-Allow-Origin:不能为通配符*,必须明确指定协议、域名和端口Access-Control-Allow-Credentials: true:启用凭据传输支持withCredentials:前端请求需设置此属性为trueapp.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'https://frontend.example.com'); res.header('Access-Control-Allow-Credentials', 'true'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); });上述代码确保来自指定前端域的请求可携带 Cookie。若缺少Access-Control-Allow-Credentials或 origin 使用通配符,浏览器将拒绝响应。fetch('https://api.example.com/profile', { method: 'GET', credentials: 'include' // 关键:包含 Cookie });credentials: 'include'确保请求自动附带同站 Cookie,实现会话保持。server { listen 80; server_name frontend.example.com; location /api/ { proxy_pass http://backend:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }上述配置将发往frontend.example.com/api/的请求代理至后端服务backend:3000,由于请求由服务器发起,不受浏览器同源策略约束。RewriteEngine On RewriteCond %{HTTP_HOST} ^api\.example-primary\.com$ [NC] RewriteRule ^/(.*)$ /primary/$1 [L] RewriteCond %{HTTP_HOST} ^api\.example-secondary\.com$ [NC] RewriteRule ^/(.*)$ /secondary/$1 [L]上述规则根据请求域名将流量分别导向不同后端目录。`[NC]`表示域名匹配忽略大小写,`[L]`标识此为最后一条匹配规则,防止后续重写干扰。RewriteCond限制来源IP,提升接口安全性ENV变量标记请求上下文,便于日志追踪Forbidden响应阻止非法路径访问<?php // 接收客户端请求并转发至后端服务 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://api.backend/service"); curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents('php://input')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); echo $response; ?>该脚本通过cURL将原始请求体透明转发,适合简单代理场景。但需注意超时设置与错误处理机制,避免阻塞主线程。