因?yàn)榫W(wǎng)站有時(shí)候需要限制特定城市身份不讓訪問(wèn),就可以ii根據(jù)客戶端IP地址獲取所屬城市進(jìn)而進(jìn)行限制訪問(wèn)。
1.技術(shù)點(diǎn)在于解決如何獲取客戶端地址,因?yàn)橛锌赡芸蛻舳耸褂昧舜砟J?,那么就需要獲取真實(shí)IP地址。
2.根據(jù)IP地址使用百度開(kāi)放API和騰訊地圖API獲取IP所在城市,限制訪問(wèn)。
具體實(shí)現(xiàn)方式:
?獲取真實(shí)IP地址
主要就是判斷三個(gè)值,存在即可
function get_client_ip() {? ? $ip_address = '';? ? if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {? ? ? ? $ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);? ? ? ? $ip_address = trim(end($ip_list));? ? }? ? else if (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) {? ? ? ? $ip_address = $_SERVER['HTTP_CLIENT_IP'];? ? }? ? else if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR'])) {? ? ? ? $ip_address = $_SERVER['REMOTE_ADDR'];? ? }? ? return $ip_address;}
?根據(jù)IP地址獲取城市地區(qū)
如果客戶端用了代理反向代理,IP地址可能會(huì)有端口號(hào),所以需要處理掉端口號(hào)。
下面使用的是騰訊地圖的API,需要去申請(qǐng)一個(gè)key,免費(fèi)的申請(qǐng)地址。獲取的IP信息根據(jù)結(jié)構(gòu)獲取IP的省份和城市信息返回即可。
https://lbs.qq.com/
function get_city() {? $realip = get_client_ip();? $realip = preg_replace('/:\d+/', '', $realip); //去除端口號(hào)??$key = '你的key';? $url="https://apis.map.qq.com/ws/location/v1/ip?ip=".$realip."&key=".$key;? // 使用curl? $curl = curl_init();? curl_setopt($curl, CURLOPT_URL, $url);? curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);? $response = curl_exec($curl);? curl_close($curl);? // 解碼JSON數(shù)據(jù)為PHP數(shù)組? $data = json_decode($response, true);? //true解析成 數(shù)據(jù)結(jié)構(gòu)? $data = $data['result']['ad_info']['province'].$data['result']['ad_info']['city'];? return $data;}
還有一個(gè)方式是使用百度開(kāi)放API,這個(gè)不需要申請(qǐng)賬號(hào),直接構(gòu)戰(zhàn)URL地址就行,具體使用哪個(gè)看識(shí)別正確率吧,在我試驗(yàn)兩個(gè)沒(méi)啥區(qū)別,兩者的區(qū)別在于返回的數(shù)據(jù)結(jié)構(gòu)會(huì)有不一樣,所以需要不同的索引值獲取到城市信息。
http://opendata.baidu.com/api.php?query=ip地址&co=&resource_id=6006
function get_city(){? $realip = get_client_ip();? $realip = preg_replace('/:\d+/', '', $realip); //去除端口號(hào)? $api = "http://opendata.baidu.com/api.php?query=" .$realip. "&co=&resource_id=6006";? $ch = curl_init();? curl_setopt($ch, CURLOPT_URL, $api);? curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);? curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);? curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);? $handles = curl_exec($ch);? curl_close($ch);? $handles = iconv('GB2312', 'UTF-8', $handles);? $arr = json_decode($handles, true);? return $arr["data"][0]["location"];}
?調(diào)用獲取的城市處理特定限制禁止訪問(wèn)
這里設(shè)置了深圳地區(qū)不讓訪問(wèn),使用php返回頭部信息404或者其他錯(cuò)誤信息。
$local = get_city();if (strpos($local,"深圳") !==false) {? header('HTTP/1.1 404 Not Found');? exit();}
?頁(yè)面URL不跳轉(zhuǎn)顯示錯(cuò)誤
如果在服務(wù)器上設(shè)置了404或者于上面的對(duì)應(yīng)的錯(cuò)誤頁(yè)面那么就可以實(shí)現(xiàn)URL地址不改變返回錯(cuò)誤頁(yè)面,下面是nginx配置404錯(cuò)誤,一般寶塔都帶有只需要把前面的#注釋解除即可
#ERROR-PAGE-START? 錯(cuò)誤頁(yè)配置,可以注釋、刪除或修改 error_page 404 /404.html;

當(dāng)然也可以弄個(gè)特定的頁(yè)面,比如給個(gè)提示啥的,提示該城市禁止訪問(wèn)等,返回給客戶端就行了。