HTTP/1.1 405 Method Not Allowed
cURL 預設使用 POST 方式請求,部分站點(如 amazon.cn)僅允許 GET,導致 405 錯誤。
<?php
$ch = curl_init();
$url = 'https://www.amazon.cn';
// 設定 Header 模擬瀏覽器行為
$header = array(
'Accept: application/json',
'Accept-Encoding: gzip',
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1); // 包含回應標頭
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 追蹤重導向
curl_setopt($ch, CURLOPT_NOBODY, 1); // 僅取標頭(HEAD 請求)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
// 關鍵:強制使用 GET 方法
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
// HTTPS 站點需跳過 SSL 驗證(或配置 CA)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// User-Agent 模擬
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11');
$html = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
var_dump($info['http_code']); // 應為 200
| 參數 | 值 | 作用 |
|---|---|---|
CURLOPT_CUSTOMREQUEST | 'GET' | 覆蓋預設 POST,強制指定 HTTP 方法 |
CURLOPT_NOBODY | 1 | 發送 HEAD 請求(不回傳 Body),配合 GET 可用 0 |
CURLOPT_HTTPHEADER | Header 陣列 | 模擬瀏覽器 Accept/Encoding,降低被擋風險 |
# 直接測試 GET
curl -v www.amazon.cn
# 測試 POST(會得到 405)
curl -v -X POST www.amazon.cn
function http_request($url, $method = 'GET', $data = null, $headers = [], $options = []) {
$ch = curl_init();
$default_options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; PHP Bot)',
CURLOPT_ENCODING => 'gzip, deflate',
];
// 合併選項
$opts = $default_options + $options;
$opts[CURLOPT_CUSTOMREQUEST] = strtoupper($method);
if ($data && in_array(strtoupper($method), ['POST', 'PUT', 'PATCH'])) {
$opts[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
}
if ($headers) {
$opts[CURLOPT_HTTPHEADER] = $headers;
}
curl_setopt_array($ch, $opts);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
return ['body' => $response, 'info' => $info];
}