更新ICP备案查询与whois查询工具

This commit is contained in:
net909
2026-01-26 12:33:15 +08:00
parent 23bb5aea41
commit 4826b8c758
6 changed files with 596 additions and 93 deletions
+2 -1
View File
@@ -20,7 +20,8 @@
"ext-zip": "*",
"ext-pdo": "*",
"ext-iconv": "*",
"khanamiryan/qrcode-detector-decoder": "1.0.5.2"
"khanamiryan/qrcode-detector-decoder": "1.0.5.2",
"cccyun/php-whois": "^1.2"
},
"require-dev": {
"symfony/var-dumper": "^4.2",
Generated
+239 -7
View File
@@ -4,8 +4,68 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "90b52d33a495d2606004dc98c6c983ae",
"content-hash": "cc447ea0a5a3bc2bf911a9ac53603245",
"packages": [
{
"name": "cccyun/php-whois",
"version": "1.2",
"source": {
"type": "git",
"url": "https://github.com/netcccyun/php-whois.git",
"reference": "c631f1c5e26e7150501a14cd25a2380f8a077ca1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/netcccyun/php-whois/zipball/c631f1c5e26e7150501a14cd25a2380f8a077ca1",
"reference": "c631f1c5e26e7150501a14cd25a2380f8a077ca1",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": ">=7.2",
"symfony/polyfill-intl-idn": "^1.27"
},
"require-dev": {
"phpunit/phpunit": "^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Iodev\\": "src/Iodev/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "caihong",
"email": "[email protected]"
}
],
"description": "PHP WHOIS provides parsed and raw whois lookup of domains and ASN routes. PHP 5.4+ and 7+ compatible ",
"homepage": "https://github.com/netcccyun/php-whois",
"keywords": [
"asn",
"domain",
"info",
"lookup",
"parser",
"php",
"query",
"routes",
"tld",
"whois",
"црщшы"
],
"support": {
"source": "https://github.com/netcccyun/php-whois/tree/1.2"
},
"time": "2025-06-25T06:54:23+00:00"
},
{
"name": "cccyun/think-captcha",
"version": "3.0.11",
@@ -315,6 +375,178 @@
},
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3",
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3",
"shasum": ""
},
"require": {
"php": ">=7.2",
"symfony/polyfill-intl-normalizer": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "[email protected]"
},
{
"name": "Trevor Rowbotham",
"email": "[email protected]"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-10T14:38:51+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "3833d7255cc303546435cb650316bff708a1c75c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
"reference": "3833d7255cc303546435cb650316bff708a1c75c",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "[email protected]"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "topthink/framework",
"version": "v6.1.5",
@@ -382,16 +614,16 @@
},
{
"name": "topthink/think-helper",
"version": "v3.1.11",
"version": "v3.1.12",
"source": {
"type": "git",
"url": "https://github.com/top-think/think-helper.git",
"reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c"
"reference": "fe277121112a8f1c872e169a733ca80bb11c4acb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/top-think/think-helper/zipball/1d6ada9b9f3130046bf6922fe1bd159c8d88a33c",
"reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c",
"url": "https://api.github.com/repos/top-think/think-helper/zipball/fe277121112a8f1c872e169a733ca80bb11c4acb",
"reference": "fe277121112a8f1c872e169a733ca80bb11c4acb",
"shasum": ""
},
"require": {
@@ -422,9 +654,9 @@
"description": "The ThinkPHP6 Helper Package",
"support": {
"issues": "https://github.com/top-think/think-helper/issues",
"source": "https://github.com/top-think/think-helper/tree/v3.1.11"
"source": "https://github.com/top-think/think-helper/tree/v3.1.12"
},
"time": "2025-04-07T06:55:59+00:00"
"time": "2025-12-26T09:58:29+00:00"
},
{
"name": "topthink/think-migration",
+130 -51
View File
@@ -21,8 +21,9 @@ class App extends Plugin
public function query(){
$domain = input('post.domain', null, 'trim');
$type = input('post.type', 'web', 'trim');
if(!$domain) return msg('error','no domain');
if(!checkdomain($domain)){
if(strpos($domain,'.') && !checkdomain($domain)){
return msg('error', '域名格式不正确!');
}
@@ -31,70 +32,148 @@ class App extends Plugin
return msg('error', '验证失败,请重新验证');
}
$cache = Db::name('querycache')->where('type', 'icp')->where('key', $domain)->find();
$cache = Db::name('querycache')->where('type', $type.'list')->where('key|subkey', $domain)->find();
if($cache && time() - strtotime($cache['uptime']) <= self::CACHE_TIME){
$array = json_decode($cache['content'], true);
return msg('ok','success',$array);
$data = Db::name('querycache')->where('type', $type.'item')->whereIn('id', implode(',',$array['list']))->select();
$list = [];
foreach($data as $row){
$list[] = json_decode($row['content'], true);
}
return msg('ok','success',['total'=>$array['total'], 'list'=>$list]);
}
$cache = Db::name('querycache')->where('type', $type.'item')->where('key|subkey', $domain)->find();
if($cache && time() - strtotime($cache['uptime']) <= self::CACHE_TIME){
$array = json_decode($cache['content'], true);
return msg('ok','success',['total'=>1, 'list'=>[$array]]);
}
try{
$result = $this->queryapi($domain);
if(!$result){
return msg('ok','success',null);
}
$result = $this->execapi($type, $domain);
}catch(Exception $e){
return msg('error', $e->getMessage());
}
Db::name('querycache')->duplicate([
'type' => 'icp',
'key' => $result['Domain'],
'content' => json_encode($result),
'uptime' => date('Y-m-d H:i:s')
])->insert([
'type' => 'icp',
'key' => $result['Domain'],
'content' => json_encode($result),
'uptime' => date('Y-m-d H:i:s')
]);
if($result['total'] > 1 && count($result['data']) > 1){
$i = 0;
foreach($result['data'] as $row){
$id = Db::name('querycache')->duplicate([
'content' => json_encode($row),
'uptime' => date('Y-m-d H:i:s')
])->insertGetId([
'type' => $type.'item',
'key' => $row['domain'],
'subkey' => $row['webLicence'],
'content' => json_encode($row),
'uptime' => date('Y-m-d H:i:s')
]);
$result['data'][$i++]['id'] = $id;
$ids[] = $id;
}
Db::name('querycache')->duplicate([
'content' => json_encode(['total'=>$result['total'], 'list'=>$ids]),
'uptime' => date('Y-m-d H:i:s')
])->insert([
'type' => $type.'list',
'key' => $domain == $result['data'][0]['domain'] ? $result['data'][0]['domain'] : $result['data'][0]['unitName'],
'subkey' => $domain == $result['data'][0]['domain'] ? $result['data'][0]['webLicence'] : $result['data'][0]['mainLicence'],
'content' => json_encode(['total'=>$result['total'], 'list'=>$ids]),
'uptime' => date('Y-m-d H:i:s')
]);
}elseif($result['total'] == 1 && count($result['data']) > 0){
$id = Db::name('querycache')->duplicate([
'content' => json_encode($result['data'][0]),
'uptime' => date('Y-m-d H:i:s')
])->insertGetId([
'type' => $type.'item',
'key' => $result['data'][0]['domain'],
'subkey' => $result['data'][0]['webLicence'],
'content' => json_encode($result['data'][0]),
'uptime' => date('Y-m-d H:i:s')
]);
$result['data'][0]['id'] = $id;
}
return msg('ok','success',$result);
return msg('ok','success',['total'=>$result['total'], 'list'=>$result['data']]);
}
private function queryapi($domain){
if(config_get('qqapi_url')){
$url = config_get('qqapi_url').'api.php?act=icpquery';
$post = 'key='.config_get('qqapi_key').'&domain='.$domain;
$data = get_curl($url, $post);
$arr = json_decode($data, true);
if(isset($arr['code']) && $arr['code']==0){
return $arr['data'];
}elseif(isset($arr['msg'])){
throw new Exception($arr['msg']);
}else{
throw new Exception('接口请求失败');
}
}elseif(config_get('yapi_token')){
$url = 'https://api.makuo.cc/api/get.other.icp?url='.urlencode($domain);
$header = ['Authorization: '.config_get('yapi_token')];
$data = get_curl($url, 0, 0, 0, 0, 0, 0, $header);
$arr = json_decode($data, true);
if(isset($arr['code']) && $arr['code']==200){
return [
'Domain' => $arr['data']['domain'],
'DomainIcpNum' => $arr['data']['icp'],
'CompanyName' => $arr['data']['unitName'],
'CompanyType' => $arr['data']['natureName'],
'AuditTime' => $arr['data']['updateRecordTime'],
];
}elseif(isset($arr['msg'])){
throw new Exception('接口请求失败,'.$arr['msg']);
}else{
throw new Exception('接口请求失败');
}
public function item(){
$id = input('post.id');
if(!$id) return msg('error','no id');
$cache = Db::name('querycache')->where('id', $id)->find();
if($cache){
$array = json_decode($cache['content'], true);
return msg('ok','success',['total'=>1, 'list'=>[$array]]);
}else{
throw new Exception('请先配置API接口参数');
return msg('ok','success',['total'=>0, 'list'=>[]]);
}
}
/**
* https://github.com/HG-ha/ICP_Query
*/
private function execapi($type, $domain){
$url = 'http://172.17.0.1:16181/query/'.$type.'?search='.urlencode($domain);
$response = get_curl($url);
$arr = json_decode($response, true);
if(isset($arr['code']) && $arr['code']==200){
$list = [];
if(isset($arr['params']['list'])){
foreach($arr['params']['list'] as $row){
$list[] = ['domain'=>isset($row['domain'])?$row['domain']:$row['serviceName'], 'mainLicence'=>$row['mainLicence'], 'webLicence'=>$row['serviceLicence'], 'unitName'=>$row['unitName'], 'unitType'=>$row['natureName'], 'updateTime'=>$row['updateRecordTime'], 'contentTypeName'=>$row['contentTypeName']];
}
}
return ['code'=>0, 'total'=>isset($arr['params']['total']) ? $arr['params']['total'] : 0, 'data'=>$list];
}elseif(isset($arr['msg'])){
throw new Exception($arr['msg']);
}else{
throw new Exception('查询接口请求失败');
}
}
private function execapi2($domain){
$timeStamp = time();
$authKey = md5("testtest" . $timeStamp);
$referer = 'https://beian.miit.gov.cn/';
$headers = ['Origin: https://beian.miit.gov.cn'];
$url = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/auth';
$post = 'authKey='.$authKey.'&timeStamp='.$timeStamp;
$response = get_curl($url, $post, $referer, 0, 1, 0, 0, $headers);
$body = substr($response, strpos($response, '{"'));
$arr = json_decode($body, true);
if(isset($arr['code']) && $arr['code']==200){
$cookie = '';
preg_match_all('/set-cookie: (.*?);/i', $response, $matchs);
foreach ($matchs[1] as $val) {
if(substr($val,-1)=='=')continue;
$cookie.=$val.'; ';
}
$token = $arr['params']['bussiness'];
$url = 'https://hlwicpfwc.miit.gov.cn/icpproject_query/api/icpAbbreviateInfo/queryByCondition';
$post = json_encode(['pageNum'=>'','pageSize'=>'','unitName'=>$domain,'serviceType'=>1]);
$headers[] = 'Content-Type: application/json; charset=UTF-8';
$headers[] = 'token: '.$token;
$response = get_curl($url, $post, $referer, $cookie, 0, 0, 0, $headers);
$arr = json_decode($response, true);
if(isset($arr['code']) && $arr['code']==200){
$list = [];
foreach($arr['params']['list'] as $row){
$list[] = ['domain'=>$row['domain'], 'mainLicence'=>$row['mainLicence'], 'webLicence'=>$row['serviceLicence'], 'unitName'=>$row['unitName'], 'unitType'=>$row['natureName'], 'updateTime'=>$row['updateRecordTime'], 'limitAccess'=>$row['limitAccess'], 'contentTypeName'=>$row['contentTypeName'], 'dataId'=>$row['dataId']];
}
return ['code'=>0, 'total'=>$arr['params']['total'], 'data'=>$list];
}elseif(isset($arr['msg'])){
throw new Exception($arr['msg']);
}else{
throw new Exception('查询接口(query)请求失败');
}
}elseif(isset($arr['msg'])){
throw new Exception($arr['msg']);
}else{
throw new Exception('查询接口(auth)请求失败');
}
}
}
+93 -25
View File
@@ -2,19 +2,33 @@
{block name="title"}{$plugin.title} - {:config_get('title')}{/block}
{block name="main"}
<style>
td{text-align: center;}
.query-title {
text-align: right;
}
.table-title th{word-break: keep-all;}
</style>
<div class="container-xl" id="app">
<div class="col-sm-12 col-md-10 col-xl-8 center-block">
<div class="col-md-12 col-xl-10 center-block">
<div class="card card-preview">
<div class="card-inner mt-3">
<div class="nya-title nk-ibx-action-item progress-rating">
<span class="nk-menu-text font-weight-bold">ICP备案查询</span>
</div>
<div class="form-group">
<label class="form-label">输入域名:</label>
<div class="form-group row">
<div class="col-12 col-sm-4 col-md-3">
<label class="form-label">查询类型:</label>
<select id="query-type" class="form-control form-control-lg" v-model="query_type">
<option value="web">域名</option>
<option value="app">App</option>
<option value="mapp">小程序</option>
<option value="kapp">快应用</option>
</select>
</div>
<div class="col-12 col-sm-8 col-md-9 mt-3 mt-sm-0">
<label class="form-label">查询内容:</label>
<div class="form-control-wrap">
<input type="text" v-model="input" placeholder="请输入域名查询,请勿使用子域名或者带http://www等字符的网址查询" class="form-control form-control-lg" @keyup.enter="query" ref="input" autocomplete="off">
<input type="text" v-model="input" placeholder="请输入域名、程序名称、备案主体或备案号" class="form-control form-control-lg" @keyup.enter="query" ref="input" autocomplete="off">
</div>
</div>
</div>
<button class="btn btn-dim btn-outline-primary btn-block card-link mb-3" @click="query" :disabled="query_disabled">
@@ -27,20 +41,47 @@ td{text-align: center;}
<div class="nya-title nk-ibx-action-item progress-rating">
<span class="nk-menu-text font-weight-bold">查询结果</span>
</div>
<div class="alert alert-warning text-center" v-if="result_code==0"><h6><em class="icon ni ni-info"></em> 没有查询到备案信息</h6></div>
<div class="col-sm-12 col-md-10 col-xl-8 center-block" v-if="result_code==1">
<div class="alert alert-warning text-center" v-if="result_total==0"><h6><em class="icon ni ni-info"></em> 没有查询到备案记录</h6></div>
<div v-if="result_total==1">
<h6>域名 <span class="text-primary">{{result_info.domain}}</span> 的信息:</h6>
<div class="table-responsive">
<table class="table table-hover table-bordered">
<tbody>
<tr><td class="query-title">域名</td><td>{{result_info.Domain}}</td></tr>
<tr><td class="query-title">备案</td><td>{{result_info.DomainIcpNum}}</td></tr>
<tr><td class="query-title">主办单位名称</td><td>{{result_info.CompanyName}}</td></tr>
<tr><td class="query-title">主办单位性质</td><td>{{result_info.CompanyType}}</td></tr>
<tr><td class="query-title">审核日期</td><td>{{result_info.AuditTime}}</td></tr>
</tbody>
</table>
<table class="table table-hover table-bordered">
<tbody>
<tr><td class="query-title">{{service_name}}</td><td>{{result_info.domain}}</td></tr>
<tr><td class="query-title">ICP备案/许可证</td><td>{{result_info.webLicence}}</td></tr>
<tr><td class="query-title">主办单位名称</td><td>{{result_info.unitName}}</td></tr>
<tr><td class="query-title">主办单位性质</td><td>{{result_info.unitType}}</td></tr>
<tr><td class="query-title">审核日期</td><td>{{result_info.updateTime}}</td></tr>
<tr><td class="query-title">网站前置审批项</td><td>{{result_info.contentTypeName}}</td></tr>
</tbody>
</table>
</div>
</div>
<div v-if="result_total>1">
<h6><span class="text-primary">{{result_input}}</span> 共查询到 <span class="text-primary">{{result_total}}</span> 条备案信息:</h6>
<div class="table-responsive">
<table class="table table-hover table-bordered">
<thead class="table-title">
<th>{{service_name}}</th><th>ICP备案/许可证号</th><th>主办单位名称</th><th>审核日期</th><th>操作</th>
</thead>
<tbody>
<tr v-for="(item,index) in result_list" :key="index">
<td>{{item.domain}}</td><td>{{item.webLicence}}</td><td>{{item.unitName}}</td><td>{{item.updateTime}}</td><td><button class="btn btn-dim btn-outline-info btn-xs" @click="show_item(index)">详情</button></td>
</tr>
</tbody>
</table>
</div>
<p v-if="result_total>10" class="text-info">当前只支持查询最新10条记录,剩余记录请使用域名或程序名称进行精确查询。</p>
</div>
</div>
</div>
<div class="card card-preview">
<div class="card-inner">
<h6><em class="icon ni ni-info"></em> 简介</h6>
<div class="accordion-inner">
<p>支持输入域名、程序名称、网站备案号、主体备案号、单位名称(个人姓名、企业名称)进行查询</p>
<p>此ICP查询工具直接对接工信部官网,非第三方接口。采用开源项目<a href="https://github.com/HG-ha/ICP_Query" target="_blank">ICP_Query</a></p>
</div>
</div>
</div>
</div>
@@ -55,9 +96,22 @@ new Vue({
data: {
query_disabled: true,
input: '',
query_type: 'web',
result_input: '',
showresult: false,
result_info: [],
result_code: 0,
result_info: {
id: '',
domain: '',
mainLicence: '',
webLicence: '',
unitName: '',
unitType: '',
updateTime: '',
contentTypeName: '',
},
service_name: '网站域名',
result_list: [],
result_total: 0,
captcha: null
},
mounted() {
@@ -83,7 +137,7 @@ new Vue({
layer.closeAll();
return alert('请先完成验证');
}
var data = {domain: that.input};
var data = {domain: that.input, type: that.query_type};
$.ajax({
url: '/api/{$plugin.alias}/query',
type: 'post',
@@ -93,12 +147,22 @@ new Vue({
success: function (data) {
layer.closeAll();
if(data.status=='ok'){
var data = data.data;
that.result_input = that.input;
that.showresult = true;
if(data.data == null){
that.result_code = 0;
}else{
that.result_code = 1;
that.result_info = data.data;
that.result_total = data.total;
that.result_list = data.list;
if(data.list.length > 0){
that.result_info = data.list[0];
}
if(that.query_type=='web' || that.query_type=='bweb'){
that.service_name = '网站域名';
}else if(that.query_type=='app' || that.query_type=='bapp'){
that.service_name = 'App名称';
}else if(that.query_type=='mapp' || that.query_type=='bmapp'){
that.service_name = '小程序名称';
}else if(that.query_type=='kapp' || that.query_type=='bkapp'){
that.service_name = '快应用名称';
}
captcha.reset();
}else{
@@ -140,11 +204,15 @@ new Vue({
},
query() {
this.checkURL();
if(this.input.trim() == ''){
if(this.input == ''){
alert('查询内容不能为空');return;
}
layer.load(0, {shade:0.1});
this.captcha.showCaptcha();
},
show_item(index){
this.result_info = this.result_list[index];
this.result_total = 1;
}
},
})
+57 -6
View File
@@ -6,13 +6,19 @@
namespace plugin\web\whois;
use app\Plugin;
use think\facade\Db;
use Iodev\Whois\Factory;
use Iodev\Whois\Exceptions\ConnectionException;
use Iodev\Whois\Exceptions\ServerMismatchException;
use Iodev\Whois\Exceptions\WhoisException;
use Exception;
class App extends Plugin
{
const CACHE_TIME = 172800;
// https://help.aliyun.com/document_detail/35793.html
const status_name = ['ok'=>'正常状态', 'addPeriod'=>'域名新注册期', 'clientDeleteProhibited'=>'注册商设置禁止删除', 'serverDeleteProhibited'=>'注册局设置禁止删除', 'clientUpdateProhibited'=>'注册商设置禁止更新', 'serverUpdateProhibited'=>'注册局设置禁止更新', 'clientTransferProhibited'=>'注册商设置禁止转移', 'serverTransferProhibited'=>'注册局设置禁止转移', 'pendingVerification'=>'注册信息审核期', 'clientHold'=>'注册商设置暂停解析', 'serverHold'=>'注册局设置暂停解析', 'inactive'=>'非激活状态', 'clientRenewProhibited'=>'注册商设置禁止续费', 'serverRenewProhibited'=>'注册局设置禁止续费', 'pendingTransfer'=>'转移过程中', 'redemptionPeriod'=>'赎回期', 'pendingDelete'=>'待删除'];
const status_name = ['ok'=>'正常状态', 'active'=>'正常状态', 'addPeriod'=>'域名新注册期', 'clientDeleteProhibited'=>'注册商设置禁止删除', 'serverDeleteProhibited'=>'注册局设置禁止删除', 'clientUpdateProhibited'=>'注册商设置禁止更新', 'serverUpdateProhibited'=>'注册局设置禁止更新', 'clientTransferProhibited'=>'注册商设置禁止转移', 'serverTransferProhibited'=>'注册局设置禁止转移', 'pendingVerification'=>'注册信息审核期', 'clientHold'=>'注册商设置暂停解析', 'serverHold'=>'注册局设置暂停解析', 'inactive'=>'非激活状态', 'clientRenewProhibited'=>'注册商设置禁止续费', 'serverRenewProhibited'=>'注册局设置禁止续费', 'pendingTransfer'=>'转移过程中', 'redemptionPeriod'=>'赎回期', 'pendingDelete'=>'待删除'];
public function index()
{
@@ -35,13 +41,58 @@ class App extends Plugin
return msg('error', '验证失败,请重新验证');
}
if(self::CACHE_TIME > 0){
$cache = Db::name('querycache')->where('type', 'whois')->where('key', $domain)->find();
if($cache && time() - strtotime($cache['uptime']) <= self::CACHE_TIME){
$array = json_decode($cache['content'], true);
return msg('ok','success',$array);
}
}
$url = 'https://whois.aite.xyz/?ajax&domain='.urlencode($domain);
$data = get_curl($url,0,'https://whois.aite.xyz/');
if(!$data) return msg('error', '查询失败,接口返回内容错误');
try {
$whois = Factory::get()->createWhois();
$info = $whois->loadDomainInfo($domain);
} catch (ConnectionException $e) {
return msg('error', '查询失败,Whois服务器连接失败');
} catch (ServerMismatchException $e) {
return msg('error', '查询失败,Whois服务器不存在');
} catch (WhoisException $e) {
return msg('error', '查询失败,'.$e->getMessage());
}
if(!$info){
return msg('ok','success',null);
}
if(strpos($data,'For more information on')){
$data = substr($data, 0, strpos($data,'For more information on'));
$data = ['domainName'=>$info->domainName, 'whoisServer'=>$info->whoisServer, 'creationDate'=>$info->creationDate ? date('Y-m-d H:i:s', $info->creationDate) : null, 'expirationDate'=>$info->expirationDate ? date('Y-m-d H:i:s', $info->expirationDate) : null, 'updatedDate'=>$info->updatedDate ? date('Y-m-d H:i:s', $info->updatedDate) : $info->updatedDate, 'nameServers'=>$info->nameServers, 'states'=>$info->states, 'owner'=>$info->owner, 'registrar'=>$info->registrar, 'dnssec'=>$info->dnssec, 'rawData'=>$info->getResponse()->text];
if(strpos($data['rawData'],'For more information on')){
$data['rawData'] = substr($data['rawData'], 0, strpos($data['rawData'],'For more information on'));
}
$status_name = array_change_key_case(self::status_name, CASE_LOWER);
if(!empty($data['states'])){
$status = [];
foreach($data['states'] as $state){
$name = null;
$key = str_replace(' ', '', strtolower($state));
if(isset($status_name[$key]))
$name = $status_name[$key];
if(!$name) {$name = $state;$state = null;}
$status[] = ['value'=>$state, 'name'=>$name];
}
$data['states'] = $status;
}
if(self::CACHE_TIME > 0){
Db::name('querycache')->duplicate([
'content' => json_encode($data),
'uptime' => date('Y-m-d H:i:s')
])->insertGetId([
'type' => 'whois',
'key' => $domain,
'content' => json_encode($data),
'uptime' => date('Y-m-d H:i:s')
]);
}
return msg('ok','success',$data);
+75 -3
View File
@@ -5,6 +5,27 @@
.query-title {
text-align: right;
}
.whois-badge {
display: block;
padding: 3px 10px;
margin: 3px 0 3px 0;
background: #f0f4ff;
color: #364a63;
border-radius: 4px;
font-size: 13px;
}
.whois-raw-data {
background: #f5f6fa;
border-radius: 4px;
padding: 15px;
white-space: pre-wrap;
word-break: break-all;
font-size: 13px;
line-height: 1.6;
color: #364a63;
max-height: 400px;
overflow-y: auto;
}
</style>
<div class="container-xl" id="app">
<div class="col-sm-12 col-md-10 col-xl-8 center-block">
@@ -29,7 +50,24 @@
<div class="nya-title nk-ibx-action-item progress-rating">
<span class="nk-menu-text font-weight-bold">查询结果</span>
</div>
<div class="border p-2" v-html="result_info" style="white-space: nowrap;overflow-x: scroll;word-break: break-all;">
<div class="alert alert-warning text-center" v-if="!result_info"><h6><em class="icon ni ni-info"></em> 没有查询到该域名Whois信息</h6></div>
<div class="col-sm-12 col-md-10 col-xl-8 center-block" v-if="result_info">
<div class="table-responsive">
<table class="table table-hover table-bordered">
<tbody>
<tr><td class="query-title">域名</td><td>{{whoisData.domainName}}</td></tr>
<tr><td class="query-title">域名所有者</td><td>{{whoisData.owner || '-'}}</td></tr>
<tr><td class="query-title">注册商</td><td>{{whoisData.registrar}}</td></tr>
<tr><td class="query-title">Whois服务器</td><td>{{whoisData.whoisServer}}</td></tr>
<tr><td class="query-title">注册时间</td><td>{{whoisData.creationDate}}</td></tr>
<tr><td class="query-title">到期时间</td><td>{{whoisData.expirationDate}}</td></tr>
<tr><td class="query-title">更新时间</td><td>{{whoisData.updatedDate}}</td></tr>
<tr><td class="query-title">域名状态</td><td><div v-for="(item, index) in whoisData.states" :key="index">{{item.name}}<span class="text-muted" v-if="item.value">{{item.value}}</span></div></td></tr>
<tr><td class="query-title">DNS服务器</td><td><span class="whois-badge" v-for="(ns, index) in whoisData.nameServers" :key="index">{{ns}}</span></td></tr>
<tr><td class="query-title">原始信息</td><td class="whois-raw-data">{{whoisData.rawData}}</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
@@ -46,7 +84,21 @@ new Vue({
query_disabled: true,
input: '',
showresult: false,
result_info: '',
result_info: false,
whoisData: {
cacheTime: '',
domainName: '',
whoisServer: '',
creationDate: '',
expirationDate: '',
updatedDate: '',
nameServers: [],
states: [],
owner: '',
registrar: '',
dnssec: '',
rawData: '',
},
captcha: null
},
mounted() {
@@ -82,8 +134,28 @@ new Vue({
success: function (data) {
layer.closeAll();
if(data.status=='ok'){
if(data.data == null){
that.result_info = false;
that.showresult = true;
captcha.reset();
return;
}
that.result_info = true;
that.whoisData = {
cacheTime: data.data.cacheTime || '',
domainName: data.data.domainName || '',
whoisServer: data.data.whoisServer || '',
creationDate: data.data.creationDate || '',
expirationDate: data.data.expirationDate || '',
updatedDate: data.data.updatedDate || '',
nameServers: Array.isArray(data.data.nameServers) ? data.data.nameServers : [],
states: Array.isArray(data.data.states) ? data.data.states : [],
owner: data.data.owner !== undefined ? data.data.owner : '',
registrar: data.data.registrar || '',
dnssec: data.data.dnssec || '',
rawData: data.data.rawData || '',
};
that.showresult = true;
that.result_info = data.data;
captcha.reset();
}else{
alert(data.message);