مرجع المطورين
مقارنة محللات DNS
استكشف توثيق API الخاص بـ مقارنة محللات DNS، بما في ذلك معلمات الطلب وحقول الاستجابة وأمثلة الشفرة ومعالجة الأخطاء لتكاملات DomScan.
مقارنة محللات DNS
قارن إجابات سجلات DNS من مزودي DoH عامين عوديين يجري الاستعلام عنهما بشكل مستقل: Cloudflare وGoogle. كلاهما خدمة global-anycast، لذلك تمثل النتائج ما رآه المزودان من مسار الطلب، وليست نقاط قياس جغرافية أو فحصاً لخوادم أسماء authoritative أو دليلاً على الانتشار العالمي.
GET
/v1/dns/propagation
معاملات الاستعلام
| المعامل | النوع | Description |
|---|---|---|
| domain مطلوب | string | النطاق الذي سيجري الاستعلام عنه عبر كل محلل مهيأ (مثل "example.com") |
| type اختياري | string | نوع السجل المراد مقارنته: A وAAAA وCNAME وMX وTXT وNS وSOA (الافتراضي: A) |
| expected اختياري | string | قيمة سجل expected اختيارية لاستخدامها أساساً للمقارنة (مثل عنوان IP جديد) |
حقول الرد
| الحقل | النوع | Description |
|---|---|---|
propagation_percentage | number | بدون expected: حجم أكبر مجموعة إجابات متطابقة مقسوماً على جميع المحللات المهيأة. مع expected: عدد التطابقات الدقيقة مع expected مقسوماً على جميع المحللات (0-100). تبقى حالات الفشل في المقام. |
fully_propagated | boolean | تكون true عندما تتفق جميع المحللات المهيأة، أو عندما تطابق جميعها expected إذا قُدمت |
consistent | boolean | تكون true فقط عندما ينجح كل محلل مهيأ ويعيد مجموعة الإجابات canonical نفسها |
unique_values | array | قيم السجلات الفريدة التي أعادتها المحللات الناجحة |
results | array | المزود والسجلات وTTL الملحوظ ووقت الاستجابة من مسار الطلب والأخطاء لكل محلل |
طلب مثال
# Compare A records across configured resolvers
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/dns/propagation?domain=example.com&type=A"
# Compare MX answers against an expected value
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/dns/propagation?domain=example.com&type=MX&expected=mail.example.com"
const domscanFetch = (url, options = {}) =>
fetch(url, {
...options,
headers: { ...options.headers, "X-API-Key": "your-api-key" },
});
const url = new URL("https://domscan.net/v1/dns/propagation");
url.searchParams.set("domain", "example.com");
url.searchParams.set("type", "A");
url.searchParams.set("expected", "203.0.113.42");
const response = await domscanFetch(url);
const data = await response.json();
// Legacy response field names are retained for API compatibility.
console.log(`Resolver convergence: ${data.propagation_percentage}%`);
console.log(`All configured resolvers match: ${data.fully_propagated}`);
// Check which servers are still showing old values
data.results
.filter(r => !r.success || !r.records.includes(data.expected_value))
.forEach(r => console.log(`${r.server.name}: ${r.records}`));
import requests
domscan = requests.Session()
domscan.headers.update({"X-API-Key": "your-api-key"})
response = domscan.get(
"https://domscan.net/v1/dns/propagation",
params={"domain": "example.com", "type": "A"}
)
data = response.json()
# Legacy response field names are retained for API compatibility.
print(f"Resolver convergence: {data['propagation_percentage']}%")
print(f"All configured resolvers match: {data['fully_propagated']}")
# Show servers with different values
for result in data['results']:
print(f"{result['server']['name']}: {result['records']}")
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func domscanGet(url string) (*http.Response, error) {
request, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
request.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
return http.DefaultClient.Do(request)
}
func main() {
resp, _ := domscanGet("https://domscan.net/v1/dns/propagation?domain=example.com&type=A")
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)
// Legacy response field names are retained for API compatibility.
fmt.Printf("Resolver convergence: %.0f%%\n", data["propagation_percentage"])
fmt.Printf("All configured resolvers match: %v\n", data["fully_propagated"])
}
require 'net/http'
require 'json'
uri = URI("https://domscan.net/v1/dns/propagation?domain=example.com&type=A")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(request) }
data = JSON.parse(response.body)
# Legacy response field names are retained for API compatibility.
puts "Resolver convergence: #{data['propagation_percentage']}%"
puts "All configured resolvers match: #{data['fully_propagated']}"
مثال الرد
{
"domain": "example.com",
"record_type": "A",
"measurement_scope": "configured_recursive_resolvers",
"percentage_basis": "resolver_convergence",
"propagation_percentage": 100,
"fully_propagated": true,
"consistent": true,
"unique_values": ["93.184.216.34"],
"results": [
{
"server": {
"name": "Cloudflare 1.1.1.1",
"ip": "1.1.1.1",
"provider": "Cloudflare",
"location": "Global anycast",
"country": "GLOBAL",
"scope": "global-anycast",
"doh_endpoint": "https://cloudflare-dns.com/dns-query"
},
"success": true,
"records": ["93.184.216.34"],
"ttl": 86400,
"response_time_ms": 12
},
{
"server": {
"name": "Google Public DNS",
"ip": "8.8.8.8",
"provider": "Google",
"location": "Global anycast",
"country": "GLOBAL",
"scope": "global-anycast",
"doh_endpoint": "https://dns.google/resolve"
},
"success": true,
"records": ["93.184.216.34"],
"ttl": 86400,
"response_time_ms": 15
}
],
"summary": {
"total_servers": 2,
"successful": 2,
"failed": 0
}
}
GET
/v1/dns/servers
اعرض مزودي DoH العامين العوديين المستخدمين للمقارنة: Cloudflare وGoogle. كلاهما محلل global-anycast، وليس نقطة قياس جغرافية أو خادم أسماء authoritative.
مثال الرد
{
"measurement_scope": "configured_recursive_resolvers",
"geographic_vantage": false,
"servers": [
{
"name": "Cloudflare 1.1.1.1",
"ip": "1.1.1.1",
"provider": "Cloudflare",
"location": "Global anycast",
"country": "GLOBAL",
"scope": "global-anycast",
"doh_endpoint": "https://cloudflare-dns.com/dns-query"
},
{
"name": "Google Public DNS",
"ip": "8.8.8.8",
"provider": "Google",
"location": "Global anycast",
"country": "GLOBAL",
"scope": "global-anycast",
"doh_endpoint": "https://dns.google/resolve"
}
],
"total": 2
}
حقول الرد
| الحقل | النوع |
|---|---|
measurement_scope |
string |
geographic_vantage |
boolean |
servers[] |
object[] |
servers[] |
object |
servers[].name |
string |
servers[].location |
string |
servers[].country |
string |
servers[].ip |
string |
servers[].provider |
string |
servers[].scope |
string |
servers[].doh_endpoint |
string |
servers[].documentation_url |
string |
servers[].format |
string |
total |
integer |
POST
/v1/dns/propagation/bulk
معاملات الجسم
| المعامل | النوع | مطلوب |
|---|---|---|
| domains | string[] | مطلوب |
| type |
string
القيم المسموحة
AAAAACNAMEMXTXTNSSOA
الافتراضي
A
|
اختياري |
| expected | string | اختياري |
حقول الرد
| الحقل | النوع |
|---|---|
results[] |
unknown[] |
meta |
object |
meta.total |
integer |
meta.succeeded |
integer |
meta.failed |
integer |
meta.max_items |
integer |
meta.credits_per_item |
integer |
meta.duration_ms |
integer |
طلب مثال
curl -X POST "https://domscan.net/v1/dns/propagation/bulk" \
-H "Content-Type: application/json" \
-H "X-API-Key: $DOMSCAN_API_KEY" \
-d '{
"domains": [
"example.com",
"cloudflare.com"
],
"type": "A"
}'
مثال الرد
{
"results": [
null
],
"meta": {
"total": 1,
"succeeded": 1,
"failed": 1,
"max_items": 10,
"credits_per_item": 1,
"duration_ms": 1
}
}