Tôi muốn sử dụng Javascript phía máy khách để thực hiện tra cứu DNS (tên máy chủ thành địa chỉ IP) như được thấy từ máy tính của khách hàng. Điều đó có thể không?
Tôi muốn sử dụng Javascript phía máy khách để thực hiện tra cứu DNS (tên máy chủ thành địa chỉ IP) như được thấy từ máy tính của khách hàng. Điều đó có thể không?
Câu trả lời:
Không có khái niệm về máy chủ hoặc địa chỉ ip trong thư viện chuẩn javascript. Vì vậy, bạn sẽ phải truy cập một số dịch vụ bên ngoài để tra cứu tên máy chủ cho bạn.
Tôi khuyên bạn nên lưu trữ cgi-bin để tra cứu địa chỉ ip của tên máy chủ và truy cập thông qua javascript.
Chỉnh sửa : Câu hỏi này khiến tôi ngứa ngáy, vì vậy tôi đã thiết lập một dịch vụ web JSONP trên Google App Engine để trả về địa chỉ ip của khách hàng. Sử dụng:
<script type="application/javascript">
function getip(json){
alert(json.ip); // alerts the ip address
}
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"> </script>
Yay, không cần proxy máy chủ.
JS thuần túy không thể. Nếu bạn có một tập lệnh máy chủ trong cùng một miền in nó ra, bạn có thể gửi một XMLHttpRequest để đọc nó.
Rất muộn, nhưng tôi đoán nhiều người vẫn sẽ hạ cánh xuống đây thông qua "Google Airlines". Một cách tiếp cận hiện đại là sử dụng WebRTC không yêu cầu máy chủ hỗ trợ.
https://hacking.ventures/local-ip-discovery-with-html5-webrtc-security-and-privacy-risk/
Mã tiếp theo là một bản sao và dán từ http://net.ipcalf.com/
// NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (function () {
var rtc = new RTCPeerConnection({iceServers:[]});
if (window.mozRTCPeerConnection) { // FF needs a channel/stream to proceed
rtc.createDataChannel('', {reliable:false});
};
rtc.onicecandidate = function (evt) {
if (evt.candidate) grepSDP(evt.candidate.candidate);
};
rtc.createOffer(function (offerDesc) {
grepSDP(offerDesc.sdp);
rtc.setLocalDescription(offerDesc);
}, function (e) { console.warn("offer failed", e); });
var addrs = Object.create(null);
addrs["0.0.0.0"] = false;
function updateDisplay(newAddr) {
if (newAddr in addrs) return;
else addrs[newAddr] = true;
var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; });
document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
}
function grepSDP(sdp) {
var hosts = [];
sdp.split('\r\n').forEach(function (line) { // c.f. http://tools.ietf.org/html/rfc4566#page-39
if (~line.indexOf("a=candidate")) { // http://tools.ietf.org/html/rfc4566#section-5.13
var parts = line.split(' '), // http://tools.ietf.org/html/rfc5245#section-15.1
addr = parts[4],
type = parts[7];
if (type === 'host') updateDisplay(addr);
} else if (~line.indexOf("c=")) { // http://tools.ietf.org/html/rfc4566#section-5.7
var parts = line.split(' '),
addr = parts[2];
updateDisplay(addr);
}
});
}
})(); else {
document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}
Phiên bản JSONP được lưu trữ hoạt động giống như một sự quyến rũ, nhưng có vẻ như nó sử dụng tài nguyên của nó vào ban đêm hầu hết các ngày (Giờ miền Đông), vì vậy tôi đã phải tạo phiên bản của riêng mình.
Đây là cách tôi đã hoàn thành nó với PHP:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
echo $_GET['callback'] . '(' . $data . ');';
?>
Sau đó, Javascript giống hệt như trước đây, chỉ không phải là một mảng:
<script type="application/javascript">
function getip(ip){
alert('IP Address: ' + ip);
}
</script>
<script type="application/javascript" src="http://www.anotherdomain.com/file.php?callback=getip"> </script>
Đơn giản như vậy!
Lưu ý phụ: Hãy chắc chắn xóa $ _GET của bạn nếu bạn đang sử dụng nó trong bất kỳ môi trường công khai nào!
Tôi biết câu hỏi này đã được hỏi cách đây rất lâu, nhưng tôi nghĩ mình sẽ đưa ra một câu trả lời mới hơn.
Bạn có thể gửi các truy vấn DNS qua HTTPS tới các trình phân giải DNS hỗ trợ nó. Tiêu chuẩn cho DOH được mô tả trong RFC 8484 .
Đây là một điều tương tự với những gì mà tất cả các câu trả lời khác gợi ý, chỉ khác rằng DoH thực sự là giao thức DNS qua HTTPS. Nó cũng là một tiêu chuẩn Internet "được đề xuất" và nó đang trở nên khá phổ biến. Ví dụ: một số trình duyệt chính hỗ trợ hoặc có kế hoạch hỗ trợ (Chrome, Edge, Firefox) và Microsoft đang trong quá trình xây dựng nó vào hệ điều hành của họ.
Một trong những mục đích của DoH là:
cho phép các ứng dụng web truy cập thông tin DNS thông qua các API trình duyệt hiện có theo cách an toàn nhất quán với Chia sẻ tài nguyên nguồn gốc chéo (CORS)
Có một công cụ mã nguồn mở được tạo đặc biệt để thực hiện tra cứu DNS từ các ứng dụng web được gọi là dohjs . Nó thực hiện các truy vấn định dạng dây DNS qua HTTPS (DoH) như được mô tả trong RFC 8484 . Nó hỗ trợ cả hai phương thức GET và POST.
Tiết lộ đầy đủ: Tôi là người đóng góp cho dohjs.
Nếu bạn không muốn bận tâm đến định dạng dây DNS, cả Google và Cloudflare đều cung cấp API JSON cho DNS qua HTTPS.
Mã Javascript mẫu để tra cứu example.com bằng API JSON DOH của Google:
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
console.log(json);
Dưới đây là các ví dụ mà RFC cung cấp cho cả GET và POST (xem https://tools.ietf.org/html/rfc8484#section-4.1.1 ):
Lấy ví dụ:
Yêu cầu mẫu đầu tiên sử dụng GET để yêu cầu "www.example.com".
: method = GET
: Scheme = https
: Authority = dnsserver.example.net
: path = / dns-query? dns = AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
accept = application / dns-message
POST ví dụ:
Cùng một truy vấn DNS cho "www.example.com", sử dụng phương thức POST sẽ là:
: method = POST
: Scheme = https
: Authority = dnsserver.example.net
: path = / dns-query
accept = application / dns-message
content-type = application / dns-message
content-length = 33<33 byte được biểu thị bằng mã hóa hex sau> 00 00 01 00 00 01 00 00 00 00 00 00 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01
Bạn có thể tìm thấy danh sách một số trình phân giải DNS công cộng hỗ trợ DNS qua HTTPS ở một số nơi:
Trong số các nguồn trên, tôi muốn nói rằng danh sách trên wiki của Curl và danh sách DNSCrypt có lẽ là đầy đủ nhất và được cập nhật thường xuyên nhất. Trang của Curl cũng bao gồm danh sách các công cụ mã nguồn mở cho DoH (máy chủ, proxy, client libs, v.v.).
Tôi biết đây là một câu hỏi cũ nhưng giải pháp của tôi có thể hỗ trợ những người khác.
Tôi thấy rằng các dịch vụ JSON (P) giúp việc này trở nên dễ dàng không tồn tại mãi mãi nhưng JavaScript sau hoạt động tốt đối với tôi tại thời điểm viết bài.
<script type="text/javascript">function z (x){ document.getElementById('y').innerHTML=x.query }</script>
<script type='text/javascript' src='http://ip-api.com/json/zero.eu.org?callback=z'></script>
Ở trên ghi IP của máy chủ của tôi trên trang được đặt nhưng tập lệnh có thể được sửa đổi để tìm bất kỳ IP nào bằng cách thay đổi 'zero.eu.org' thành một tên miền khác. Bạn có thể thấy điều này đang hoạt động trên trang của tôi tại: http://meon.zero.eu.org/
Có một dịch vụ của bên thứ ba cung cấp API REST thân thiện với CORS để thực hiện tra cứu DNS từ trình duyệt - https://exana.io/tools/dns/
Như nhiều người đã nói bạn cần sử dụng dịch vụ bên ngoài và gọi nó. Và điều đó sẽ chỉ giúp bạn có được độ phân giải DNS từ góc độ máy chủ.
Nếu điều đó đủ tốt và nếu bạn chỉ cần phân giải DNS, bạn có thể sử dụng vùng chứa Docker sau:
https://github.com/kuralabs/docker-webaiodns
Điểm cuối:
[GET] /ipv6/[domain]
: Thực hiện phân giải DNS cho miền nhất định và trả về các địa chỉ IPv6 được liên kết.
{
"addresses": [
"2a01:91ff::f03c:7e01:51bd:fe1f"
]
}
[GET] /ipv4/[domain]
: Thực hiện phân giải DNS cho miền nhất định và trả về các địa chỉ IPv4 được liên kết.
{
"addresses": [
"139.180.232.162"
]
}
Khuyến nghị của tôi là bạn nên thiết lập máy chủ web của mình để đảo ngược proxy tới vùng chứa trên một điểm cuối cụ thể trong máy chủ phục vụ Javascript của bạn và gọi nó bằng các hàm Ajax Javascript tiêu chuẩn của bạn.
Có một thư viện javascript DNS-JS.com thực hiện điều này.
DNS.Query("dns-js.com",
DNS.QueryType.A,
function(data) {
console.log(data);
});
Firefox có một API tích hợp cho việc này kể từ v60, dành cho WebExtensions:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns/resolve
browser
không tồn tại trong Firefox 64 beta nên tôi tự hỏi liệu điều đó có bị xóa hay không.
dns
cho phép và tập lệnh sẽ không chạy dưới dạng kịch bản nội dung (một lần nữa, browser.dns
sẽ không được hiển thị ở đó)
chắc chắn bạn có thể làm điều đó mà không cần sử dụng bất kỳ bổ sung nào, chỉ cần javascript thuần túy, bằng cách sử dụng phương pháp dns này browser.dns.resolve("example.com");
nhưng nó chỉ tương thích với FIREFOX 60, bạn có thể xem thêm thông tin trên MDN https://developer.mozilla.org/en-US/docs / Mozilla / Tiện ích bổ sung / WebExtensions / API / dns / giải quyết
Tôi không nghĩ rằng điều này được cho phép bởi hầu hết các trình duyệt vì lý do bảo mật, trong bối cảnh JavaScript thuần túy như câu hỏi đặt ra.
Có thể tôi đã bỏ sót điểm nhưng để trả lời cho anh chàng NAVY đây là cách trình duyệt có thể cho bạn biết địa chỉ IP của 'người yêu cầu' (mặc dù có thể chỉ là nhà cung cấp dịch vụ của họ).
Đặt một thẻ script trong trang sẽ được hiển thị bởi ứng dụng khách gọi (có src trỏ đến) một máy chủ khác không được tải cân bằng (Tôi nhận thấy rằng điều này có nghĩa là bạn cần truy cập vào máy chủ thứ hai nhưng ngày nay máy chủ lưu trữ rất rẻ và bạn có thể thiết lập điều này dễ dàng và rẻ).
Đây là loại mã cần được thêm vào trang khách hàng:
Trên máy chủ khác "someServerIown", bạn cần có trang ASP, ASPX hoặc PHP;
----- chứa mã máy chủ như thế này:
"<% Response.Write (" var clientipaddress = '"& Request.ServerVariables (" REMOTE_ADDR ") &"'; ")%>" (không có dấu ngoặc kép dbl bên ngoài :-))
---- và viết mã này trở lại thẻ script:
var clientipaddress = '178.32.21.45';
Điều này có hiệu quả tạo ra một biến Javascript mà bạn có thể truy cập bằng Javascript trên trang.
Hy vọng rằng bạn truy cập vào var này và ghi giá trị vào một điều khiển biểu mẫu sẵn sàng để gửi lại.
Khi người dùng đăng hoặc nhận được yêu cầu tiếp theo Javascript và / hoặc biểu mẫu của bạn sẽ gửi giá trị của biến mà "otherServerIown" đã điền cho bạn, quay lại máy chủ mà bạn muốn.
Đây là cách tôi đi vòng quanh bộ cân bằng tải ngu ngốc mà chúng tôi có để che đi địa chỉ IP của máy khách và làm cho nó xuất hiện dưới dạng của bộ cân bằng tải .... ngu ngốc ... chết lặng!
Tôi chưa đưa ra giải pháp chính xác vì tình hình của mọi người hơi khác nhau. Tuy nhiên, khái niệm là âm thanh. Ngoài ra, hãy lưu ý nếu bạn đang thực hiện việc này trên trang HTTPS "OtherServerIOwn" của bạn cũng phải gửi ở dạng bảo mật đó nếu không Khách hàng sẽ được cảnh báo về nội dung hỗn hợp. Và nếu bạn có https thì hãy đảm bảo TẤT CẢ các chứng chỉ của bạn đều hợp lệ, nếu không khách hàng cũng nhận được cảnh báo.
Hy vọng nó sẽ giúp một ai đó! Xin lỗi, đã mất một năm để trả lời / đóng góp. :-)
Phiên bản của tôi như thế này:
php trên máy chủ của tôi:
<?php
header('content-type: application/json; charset=utf-8');
$data = json_encode($_SERVER['REMOTE_ADDR']);
$callback = filter_input(INPUT_GET,
'callback',
FILTER_SANITIZE_STRING,
FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);
echo $callback . '(' . $data . ');';
?>
jQuery trên trang:
var self = this;
$.ajax({
url: this.url + "getip.php",
data: null,
type: 'GET',
crossDomain: true,
dataType: 'jsonp'
}).done( function( json ) {
self.ip = json;
});
Nó hoạt động trên nhiều miền. Nó có thể sử dụng một kiểm tra trạng thái. Làm việc về điều đó.
Nếu máy khách đã cài đặt Java, bạn có thể làm như sau:
ipAddress = java.net.InetAddress.getLocalHost().getHostAddress();
Ngoài ra, bạn có thể sẽ phải sử dụng tập lệnh phía máy chủ.