初衷
想对接企业微信,或者做一个简单的HTML单页,比起开官网和小程序查快多了。
在批量查询时,可以直接通过Python调用,比起官网的批量查询要灵活得多(官网的还要先用Python生成列表再复制,而且一次查太多网页还容易出问题)。
PHP部署方便,而且腾讯云云API调用有每秒频次限制,不需要多快,很适用。
比起每个应用独自调用腾讯云API去折腾SDK或者签名流程,套一层后只需传入域名即可查询,显然要方便很多。
代码
<?php
// 请求外部资源
// 参数:$url,字符串。$post,array。$httpheader,字符数组。
function getHttpResponse_h($url, $post = false,$httpheader, $timeout = 10){
// 要先用json_encode()处理,不然就是表单而不是json数据了
// 传入的数据里要带上Content-Type,标明是application/json
$po = json_encode($post);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// $httpheader[] = "Accept: */*";
// $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
// $httpheader[] = "Connection: close";
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if($post){
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $po);
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
if((!isset($_GET['domain'])or($_GET['domain'] == ""))){
echo "无参数";
exit;
}
$domainname = $_GET['domain'];
$secretId = "填写自己的";
$secretKey = "填写自己的";
$host = "domain.tencentcloudapi.com";
$service = "domain";
$version = "2018-08-08";
$action = "CheckDomain";
$region = "ap-guangzhou";
$timestamp = time();
// $timestamp = 1662042540;
$algorithm = "TC3-HMAC-SHA256";
// step 1: build canonical request string
$httpRequestMethod = "POST";
$canonicalUri = "/";
$canonicalQueryString = "";
$canonicalHeaders = "content-type:application/json"."\n"."host:".$host."\n";
$signedHeaders = "content-type;host";
$payload = '{"DomainName":"'.$domainname.'"}';
$hashedRequestPayload = hash("SHA256", $payload);
$canonicalRequest = $httpRequestMethod."\n"
.$canonicalUri."\n"
.$canonicalQueryString."\n"
.$canonicalHeaders."\n"
.$signedHeaders."\n"
.$hashedRequestPayload;
// echo $canonicalRequest.PHP_EOL;
// echo "<br><br>";
// step 2: build string to sign
$date = gmdate("Y-m-d", $timestamp);
$credentialScope = $date."/".$service."/tc3_request";
$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
$stringToSign = $algorithm."\n"
.$timestamp."\n"
.$credentialScope."\n"
.$hashedCanonicalRequest;
// echo $stringToSign.PHP_EOL;
// echo "<br><br>";
// step 3: sign string
$secretDate = hash_hmac("SHA256", $date, "TC3".$secretKey, true);
$secretService = hash_hmac("SHA256", $service, $secretDate, true);
$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
// echo $signature.PHP_EOL;
// echo "<br><br>";
// step 4: build authorization
$authorization = $algorithm
." Credential=".$secretId."/".$credentialScope
.", SignedHeaders=content-type;host, Signature=".$signature;
// echo $authorization.PHP_EOL;
// echo "<br><br>";
$curl = "curl -X POST https://".$host
.'<br>{"Authorization": "'.$authorization.'",<br>'
.'"Content-Type": "application/json",<br>'
.'"Host": "'.$host.'",<br>'
.'"X-TC-Action": "'.$action.'",<br>'
.'"X-TC-Timestamp": "'.$timestamp.'",<br>'
.'"X-TC-Version": "'.$version.'",<br>'
.'"X-TC-Region": "'.$region.'"}<br>'
." -d '".$payload."'";
// echo $curl.PHP_EOL;
$he = ['Authorization: '.$authorization,
'Content-Type: application/json',
'Host: '.$host,
'X-TC-Action: '.$action,
'X-TC-Timestamp: '.$timestamp,
'X-TC-Version: '.$version,
'X-TC-Region: '.$region];
$post_data = array("DomainName" => $domainname);
$output = getHttpResponse_h($url = "https://".$host,$post = $post_data,$httpheader = $he);
// echo($output);
$outjson = json_decode($output,true);
$is_no = $outjson['Response']['Available'];
// $ResponseDat = $outjson['Response'];
// echo json_encode($ResponseDat);
// 判断有无错误消息
if(!isset($outjson['Response']['Error'])){
if($is_no == false){
echo("已注册");
}elseif ($is_no == true) {
echo("未注册");
}
}else{
echo($outjson['Response']['Error']['Code']);
}
代码升级
腾讯云云API每秒10次的调用限制很容易碰上。
唯一的解决方法是准备多个账号,但账号分配成了问题。
使用场景:个人使用
均匀分配
统计每个账户调用次数,每次选择最小的使用。
问题:还得弄数据库什么的,太麻烦。
随机(入选)
每次随机选一个账户访问
问题:脸黑的人可能10次都是同一个
超限自动切换
如果超出限制了,自动切换另一个账号再次调用。
问题:这个有点离题了,因为目标是避开限制,节省多次请求消耗的时间,而不是遇到限制如何处理。搭配其他的使用倒是不错。
代码
如果多个账户要按需修改(随机数生成和列表两地方)
$domainname = $_GET['domain'];
$acc_id_list = [["账户一secretId","账户一secretKey "],["账户二secretId","账户二secretKey "]];
$indexP = rand(0,1);
$secretId = $acc_id_list[$indexP][0];
$secretKey = $acc_id_list[$indexP][1];
$host = "domain.tencentcloudapi.com";
API返回值研究(部分)
错误返回值
常见的就两种,一种是签名错误,这个一般在早期出现:
{
"Response": {
"Error": {
"Code": "AuthFailure.SignatureFailure",
"Message": "The provided credentials could not be validated. Please check your signature is correct."
},
"RequestId": "9920bce6-81de-4f2c-bd22-7f95eaad28d8"
}
}
一种是每秒调用数超出限制,这个比较常见:
{
"Response": {
"Error": {
"Code": "RequestLimitExceeded",
"Message": "Your current request times equals to `28` in a second, which exceeds the frequency limit `10` for a second. Please reduce the frequency of calls."
},
"RequestId": "fd5f460b-3eb7-4a48-a00b-4a39b3fee63b"
}
}
域名无法注册的返回值
常见的有两种,一种是被注册了没法注册
"该域名已被注册,请选择其他域名"
{
"Response": {
"DomainName": "ius.cn",
"FeeTransfer": 0,
"RequestId": "2957fcbd-bfb9-48c8-a867-e0a9956d26ec",
"RealPrice": 29,
"BlackWord": false,
"FeeRenew": 0,
"Available": false,
"Premium": false,
"RecordSupport": true,
"Price": 35,
"Describe": "",
"FeeRestore": 0,
"Period": 1,
"Reason": "\u8be5\u57df\u540d\u5df2\u88ab\u6ce8\u518c\uff0c\u8bf7\u9009\u62e9\u5176\u4ed6\u57df\u540d"
}
}
一种是含敏感词无法注册(至少在腾讯云无法注册,别的平台不清楚),但要注意,这只能说明这个域名有敏感词,不能说明没有被注册,腾讯云的逻辑是先检查敏感与否再检查是否被注册了。
"域名包含敏感词不可注册,请选择其他域名"
{
"Response": {
"DomainName": "xxx.cn",
"FeeTransfer": 0,
"RequestId": "398ad69e-32fb-4286-908a-05f684e755f6",
"RealPrice": 29,
"BlackWord": true,
"FeeRenew": 0,
"Available": false,
"Premium": false,
"RecordSupport": true,
"Price": 35,
"Describe": "",
"FeeRestore": 0,
"Period": 1,
"Reason": "\u57df\u540d\u5305\u542b\u654f\u611f\u8bcd\u4e0d\u53ef\u6ce8\u518c\uff0c\u8bf7\u9009\u62e9\u5176\u4ed6\u57df\u540d"
}
}
编写笔记
通过curl发送json格式数据的post请求(发送表单数据按代码注释修改)
// 请求外部资源
// 参数:$url,字符串。$post,array。$httpheader,字符数组。
function getHttpResponse_h($url, $post = false,$httpheader, $timeout = 10) {
// 要先用json_encode()处理,不然就是表单而不是json数据了
// 传入的数据里要带上Content-Type,标明是application/json
$po = json_encode($post);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// $httpheader[] = "Accept: */*";
// $httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
// $httpheader[] = "Connection: close";
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if($post) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $po);
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
腾讯云API文档签名代码修改
在第一步,文档里的代码是
$canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$host."\n";
但是在这次测试里这样写会报错AuthFailure.SignatureFailure
修改成下面这样就不报错了
$canonicalHeaders = "content-type:application/json"."\n"."host:".$host."\n";