首页 > PHP > 跨域 php代码解决办法

跨域 php代码解决办法

2025-04-02 11:17:36

跨域的问题根源和常见发生问题,点这里查看


核心代码示例

<?php
// 允许的域名(需明确指定,不能使用通配符 *)
$allowedOrigins = [
    'https://your-frontend-domain.com',
    'https://your-miniprogram-domain.com' // 小程序域名(需配置)
];

$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowedOrigins)) {
    header("Access-Control-Allow-Origin: {$origin}");
}

// 允许携带 Cookie 等凭证
header("Access-Control-Allow-Credentials: true");

// 允许的请求方法(根据需求调整)
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");

// 允许的请求头(包含自定义头)
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");

// 暴露自定义响应头(可选)
header("Access-Control-Expose-Headers: X-Custom-Header");

// 处理预检请求(OPTIONS)
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header("HTTP/1.1 204 No Content");
    exit;
}

// ---------- 业务逻辑代码 ----------
// 示例:设置 Cookie(需在 CORS 配置后执行)
setcookie('user_token', 'token_value', [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => '.your-domain.com', // 主域名共享 Cookie
    'secure' => true, // 仅 HTTPS
    'httponly' => true,
    'samesite' => 'None' // 跨站传递 Cookie 必须设置
]);

// 返回 JSON 数据
header('Content-Type: application/json');
echo json_encode(['status' => 'success']);
?>

关键说明

  1. Cookie 安全要求

    • Access-Control-Allow-Origin 必须明确指定域名(不能为 *
    • Access-Control-Allow-Credentials: true 必须设置
    • Cookie 需设置 SameSite=None; Secure(仅 HTTPS 生效)
  2. 预检请求处理

    • 对 OPTIONS 方法直接返回 204,避免触发业务逻辑
  3. 多域名管理

    • 通过 $allowedOrigins 数组动态控制允许的域名

二、小程序跨域适配方案

1. 小程序配置要求

  • 域名白名单:在小程序后台 开发设置 -> 服务器域名 中添加 PHP 服务的域名

    • request 合法域名
    • uploadFile 合法域名(如果涉及文件上传)
    • downloadFile 合法域名(如果涉及文件下载)
  • HTTPS 强制要求:小程序必须使用 HTTPS 协议

2. PHP 服务端适配

无需特殊修改,保持上述 CORS 配置即可(小程序请求会自动携带 Origin 头)

3. 小程序端请求示例

// 微信小程序端代码
wx.request({
  url: 'https://your-php-service.com/api',
  method: 'POST',
  data: { key: 'value' },
  header: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token' // 自定义头
  },
  success: (res) => {
    console.log(res.data);
  },
  fail: (err) => {
    console.error('请求失败', err);
  }
})

三、常见问题排查

场景1:Cookie 无法跨域携带

  • 检查项:
    • 服务端是否设置 Access-Control-Allow-Credentials: true
    • Cookie 是否设置 SameSite=None; Secure
    • 请求是否使用 HTTPS
    • 前端请求是否设置 withCredentials(浏览器端需要)

场景2:小程序报错 "不在以下 request 合法域名列表"

  • 解决方法:
    1. 登录小程序后台,添加服务端域名到合法域名列表
    2. 真机调试时,可临时勾选开发者工具中的 不校验合法域名 选项(仅限开发环境)

场景3:自定义头被拦截

  • 解决方案:
    • 服务端需在 Access-Control-Allow-Headers 中明确列出自定义头(如 Authorization

四、安全增强建议

  1. 严格限制域名白名单

    // 生产环境推荐使用精确匹配
    $allowedOrigins = ['https://trusted-domain.com'];
    
  2. 限制 Cookie 作用域

    setcookie(..., [
      'domain' => 'api.your-domain.com', // 限定子域名
      'path' => '/secure' // 限定路径
    ]);
    
  3. 签名验证(小程序场景)

    // 验证小程序请求签名(需获取 session_key)
    $signature = $_GET['signature'];
    $rawData = $_GET['rawData'];
    if (!validateWechatSignature($rawData, $signature)) {
      http_response_code(403);
      exit;
    }
    

 

 

 

使用 Ctrl+D 可将网站添加到书签
收藏网站
扫描二维码
关注早实习微信公众号
官方公众号
Top