Web 应用程序正变得越来越个性化。此外,出于多种原因,使用基于位置的服务的 Web 应用程序正在兴起。它可以用于隐私、安全或任何特定的基于位置的功能。
通过了解用户的位置,您可以轻松提供不同的功能,例如个性化内容、良好的安全性、天气预报、更多的本地化和更好的用户体验。作为开发人员,了解如何为您的 Web 应用程序获取用户位置至关重要。在本文中,我们将带您逐步了解如何使用React.js等现代网络技术获取用户的位置。我们将介绍获取用户 IP 地址的不同方法,以及如何从用户那里获取更多的地理定位数据。那么,让我们开始吧!
首先,让我们了解什么是IP或IP 地址。
每个使用互联网的设备都有一个唯一的地址,就像每个房子都有一个唯一的号码或地址一样。设备的这个唯一地址称为IP 地址。它帮助设备通过互联网相互通信。
在这里, IP代表“Internet 协议” ,它是设备用来通过 Internet 相互通信的一组规则。现在让我们了解Geolocation 。
地理位置是两个词的组合。第一个是“Geo” ,意思是地球,第二个词是“ location” ,意思是某物在地球上的位置。
因此, “IP-Geolocation”是一种根据IP 地址查找设备物理位置的方法。 IP 地理定位数据的准确性取决于不同的因素,例如使用哪种方法获取数据、数据质量、设备类型等。移动设备的数据可能不太准确,因为这些设备经常更换网络。现在让我们看看如何在 React 中获取用户的 IP 地址。
我们可以通过多种方法获取用户的位置。对于本文,我们将使用所有浏览器都支持的Geolocation API ,我们无需安装任何其他第三方库即可使用它。要获取更多数据,我们可以使用来自第三方服务的 API,例如Geocoding API 。
首先让我们使用vite创建一个 React 应用程序。打开 CMD 或终端,然后找到您的项目文件夹并使用以下命令。
npm create vite@latest your-app-name
执行上述命令后,它会显示一个框架列表,现在使用箭头键从列表中选择React ,然后按 Enter。
现在它将显示一个变体列表,从这些变体中选择Javascript 。然后它将创建一个包含您的应用程序名称的文件夹并添加所有必要的文件。现在使用以下命令安装所有必需的库并运行开发服务器。
cd your-app-name
此命令会将当前目录更改为应用程序目录npm install
使用此命令,我们将安装所有必需的库npm run dev
此命令可能会在 localhost:5173 启动开发服务器
现在开发服务器已启动并正在运行,让我们获取用户的 IP 地址。
Geolocation API允许用户根据需要提供他们的位置。此方法仅在用户授予访问其位置的权限时才有效,否则此基于浏览器的 API 将无法获取 IP 地址。如果您的 Web 应用程序上的功能确实需要用户的位置,那么您可以用一条好的文本消息提示用户,让他们知道您为什么需要他们的位置。
通过调用navigator.geolocation
可以访问此 Geolocation API,navigator.geolocation 是一个可以返回 Geolocation 对象的属性。让我们看看什么是navigator 。
导航器:它是一个接口,表示用户代理(浏览器)的状态和身份。让我们记录这个导航器并查看它提供的其他属性。
打开App.jsx文件并清除 return 语句中的所有代码,只保留App
类的父div
,然后在useEffect
中使用console.log(navigator)
,如以下代码所示。
import { useEffect } from "react"; import "./App.css"; function App() { useEffect(() => { console.log(navigator); }, []); return <div className="App"></div>; } export default App;
在开发服务器选项卡中,按 F12 或单击鼠标右键打开控制台。您将看到不同属性的列表,例如appCodeName 、 Bluetooth 、 clipboard 、 geolocation等。让我们记录地理定位。只需像这样在日志中添加地理位置console.log(navigator.geolocation)
。在控制台中,您将看到一个空对象,因为我们暂时没有访问地理位置的权限,所以让我们看看如何获得此权限。看看下面的代码和解释。
useEffect(() => { if (navigator.geolocation) { navigator.permissions .query({ name: "geolocation" }) .then(function (result) { console.log(result); }); } else { console.log("Geolocation is not supported by this browser."); } }, []);
在上面的useEffect
中,首先我们会检查是否有 navigator。地理定位与否,如果是真的,我们将检查权限。
这里,
navigator.permissions:返回一个Permissions对象,可用于查询和更新权限状态。
query:它是 Permission 的一种方法,它返回用户权限的状态。它采用一个对象,该对象具有以逗号分隔的名称-值对列表。这里我们已经通过了geolocation,因为我们想知道geolocation权限的状态。
在这里我们得到了一个 Promise,这就是为什么我们将使用then
关键字并记录结果的原因。如果您检查浏览器的控制台,您将看到以下对象。
{ name: "geolocation", onchange: null, state: "prompt" }
状态可以有 3 个不同的值,
对于“granted”和“prompt”状态,我们可以创建一个函数来获取用户的当前位置,但对于“ denied ”状态,我们可以显示如何在浏览器中启用位置权限的说明。
注意:如果用户已经拒绝位置权限,则无法再次提示位置权限,除非用户在其浏览器中手动启用它。
让我们对所有 3 个权限状态使用 3 个条件,如下所示
useEffect(() => { if (navigator.geolocation) { navigator.permissions .query({ name: "geolocation" }) .then(function (result) { console.log(result); if (result.state === "granted") { //If granted then you can directly call your function here } else if (result.state === "prompt") { //If prompt then the user will be asked to give permission } else if (result.state === "denied") { //If denied then you have to show instructions to enable location } }); } else { console.log("Geolocation is not supported by this browser."); } }, []);
在prompt
状态下,让我们使用名为getCurrentPosition的函数。此函数采用以下参数。
让我们实现所有 3 个参数。首先让我们创建一个成功函数。在useEffect
之前添加以下成功函数。
function success(pos) { var crd = pos.coords; console.log("Your current position is:"); console.log(`Latitude : ${crd.latitude}`); console.log(`Longitude: ${crd.longitude}`); console.log(`More or less ${crd.accuracy} meters.`); }
此回调函数将返回一个位置对象,该对象具有坐标,即坐标。您可以从坐标中获取latitude 、 longitude 、 accuracy等值。现在在成功函数之后添加以下错误函数。
function errors(err) { console.warn(`ERROR(${err.code}): ${err.message}`); }
让我们也声明一个选项对象,
var options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0, };
现在将以下行粘贴到“提示”和“授予”条件中,并在浏览器中检查输出。
navigator.geolocation.getCurrentPosition(success, errors, options)
您可以在浏览器中看到一个提示,要求您提供位置权限。授予权限后,您可以在控制台选项卡中看到坐标值。这是完整的代码。
import { useEffect } from "react"; import "./App.css"; function App() { var options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0, }; function success(pos) { var crd = pos.coords; console.log("Your current position is:"); console.log(`Latitude : ${crd.latitude}`); console.log(`Longitude: ${crd.longitude}`); console.log(`More or less ${crd.accuracy} meters.`); } function errors(err) { console.warn(`ERROR(${err.code}): ${err.message}`); } useEffect(() => { if (navigator.geolocation) { navigator.permissions .query({ name: "geolocation" }) .then(function (result) { console.log(result); if (result.state === "granted") { //If granted then you can directly call your function here navigator.geolocation.getCurrentPosition(success, errors, options); } else if (result.state === "prompt") { //If prompt then the user will be asked to give permission navigator.geolocation.getCurrentPosition(success, errors, options); } else if (result.state === "denied") { //If denied then you have to show instructions to enable location } }); } else { console.log("Geolocation is not supported by this browser."); } }, []); return <div className="App"></div>; } export default App;
就是这样。这就是您可以轻松获取任何设备的经纬度值的方法。现在这些信息还不够,所以让我们使用opencage 的反向地理编码 API来获取有关用户位置的更多信息。
我们已经获得了有关用户设备的纬度和经度信息,现在让我们看看如何使用它来获取有关其位置的更多信息。我们将使用opencage中的 API 来获取有关该位置的更多信息。因此,请务必注册并获取 API 密钥。您无需支付任何费用,因为 opencage 在免费试用中每天提供 2,500 个请求。您可以从他们的网站上查看有关定价的更多信息。我使用过 Opencage 的 API,因为它们可以免费试用并且也没有 CORS 限制。现在让我们创建一个函数来使用这个 API。
const [location, setLocation] = useState(); function getLocationInfo(latitude, longitude) { const url = `https://api.opencagedata.com/geocode/v1/json?q=${latitude},${longitude}&key=${APIkey}`; fetch(url) .then((response) => response.json()) .then((data) => { console.log(data); if (data.status.code === 200) { console.log("results:", data.results); setLocation(data.results[0].formatted); } else { console.log("Reverse geolocation request failed."); } }) .catch((error) => console.error(error)); }
此getLocationInfo函数获取纬度和经度,然后使用 opencage文档中的 URL,该文档获取纬度、经度和 API 密钥。在此函数中,我们使用 fetch 从 URL 获取数据,如果状态代码为200 ,则我们将数据存储在位置状态中。您可以在浏览器上检查您的控制台以查看您正在获取哪种类型的数据。现在,我们使用格式化属性的值。要获取有关响应对象的更多信息,您可以查看文档。现在让我们从已经定义的成功函数中调用这个函数。
function success(pos) { var crd = pos.coords; ... ... getLocationInfo(crd.latitude, crd.longitude); }
现在,只要用户同意提供他的位置, success函数就会运行,它还会将纬度和经度信息传递给getLocationInfo函数并执行它。您可以使用此位置状态在您的网络应用程序中显示位置。
import { useEffect, useState } from "react"; import "./App.css"; const APIkey = "Enter-your-api-key"; function App() { const [location, setLocation] = useState(); function getLocationInfo(latitude, longitude) { const url = `https://api.opencagedata.com/geocode/v1/json?q=${latitude},${longitude}&key=${APIkey}`; fetch(url) .then((response) => response.json()) .then((data) => { console.log(data); if (data.status.code === 200) { console.log("results:", data.results); setLocation(data.results[0].formatted); } else { console.log("Reverse geolocation request failed."); } }) .catch((error) => console.error(error)); } var options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0, }; function success(pos) { var crd = pos.coords; console.log("Your current position is:"); console.log(`Latitude : ${crd.latitude}`); console.log(`Longitude: ${crd.longitude}`); console.log(`More or less ${crd.accuracy} meters.`); getLocationInfo(crd.latitude, crd.longitude); } function errors(err) { console.warn(`ERROR(${err.code}): ${err.message}`); } useEffect(() => { if (navigator.geolocation) { navigator.permissions .query({ name: "geolocation" }) .then(function (result) { console.log(result); if (result.state === "granted") { //If granted then you can directly call your function here navigator.geolocation.getCurrentPosition(success, errors, options); } else if (result.state === "prompt") { //If prompt then the user will be asked to give permission navigator.geolocation.getCurrentPosition(success, errors, options); } else if (result.state === "denied") { //If denied then you have to show instructions to enable location } }); } else { console.log("Geolocation is not supported by this browser."); } }, []); return ( <div className="App"> {location ? <>Your location: {location}</> : null} </div> ); } export default App;
您还可以实现错误状态,当 API 或函数无法正确获取数据时显示错误消息。还要在函数上实现所需的错误处理方法。这是您可以获得有关设备位置的大量信息的方法。现在让我们看看如何获取设备的 IP 地址。
为了在客户端获取用户的 IP 地址,我们将使用ipify ,这是一个简单的公共 IP 地址 API。我们将创建另一个useEffect
并创建一个函数来获取 IP 地址,如以下代码块所示。
const [ipAddress, setIpAddress] = useState(''); useEffect(() => { const fetchIp = async () => { try { const response = await fetch('https://api.ipify.org?format=json'); const data = await response.json(); setIpAddress(data.ip); } catch (error) { console.error(error); } }; fetchIp(); }, []);
在上面的代码中,我们创建了一个名为ipAddress
的状态来存储 IP 地址。 ipfy是一个公共 API,因此我们不需要任何 API 密钥,我们可以直接使用 URL。在useEffect
中,我们创建了一个名为fetchIp
异步函数,它将获取 IP 地址并将其存储在ipAddress
状态中。不要忘记在useEffect
中调用fetchIp
函数。
这是您可以轻松获取设备 IP 地址的方法。有多个 API 提供此类服务。对于服务器端,一般可以从用户向你发送的获取网页或任何数据的请求中获取IP地址。但是,您不应仅依赖 IP 地址,因为某些 ISP 使用共享 IP 地址,这意味着多个用户可能拥有相同的 IP 地址。此外,一些用户也使用 VPN 和代理。
当涉及到用户数据时,它始终是任何应用程序中的关键部分。作为开发人员,我们的工作是创建以用户为中心并保护用户数据的应用程序。对于设备位置等数据,开发人员可能面临许多问题,例如,
实施基于位置的功能可能具有挑战性,但通过遵循最佳实践,您可以为用户提供更加个性化和安全的体验。处理基于位置的数据时,请记住以下几点。
准确性:使用 IP 地址时,您应该使用多个 api 仔细检查它并交叉检查位置。您必须在基于位置的服务和功能中包含回退机制。最好验证数据,因为位置数据可能会受到设备设置、网络连接等因素的影响。
隐私:这是收集任何用户数据时的主要关注点,因为您必须遵守多个国家/地区的不同法律。开发人员应始终尊重用户的隐私。在收集用户的任何数据时,有必要制定清晰简洁的隐私政策。每当您收集任何敏感信息时,您都必须告知用户。如果有任何基于位置的功能,那么您应该清楚地说明为什么以及如何使用这些数据。此外,您应该为用户提供选择退出选项,这样如果他们不想共享他们的数据,他们可以轻松选择退出。
安全性:为了数据的安全性,您可以实施 OAuth 或 JWT 等身份验证机制,并保护 API 端点免受任何未经授权的访问。您应该始终建议用户使用强密码、更新浏览器等。您必须使用 HTTPS 和 SSL 证书加密数据,以确保客户端和服务器之间的安全通信。在后端,您可以实施基于角色的访问控制,以便只有选定的用户(例如只有管理员)才能访问数据。在更新任何依赖项之前,您应该始终检查它是否来自官方来源。
当涉及到用户的个性化体验时,位置数据起着重要作用,但是,处理这些数据也是一项至关重要的任务。您可以使用许多不同的方法来获取位置数据,但这取决于您需要多少数据,如果您只需要一个 IP 地址,那么您可以使用ipify API,如果您需要更多地理定位数据,那么您可以使用opencage或google 的反向地理编码 API 。如果您正在构建天气应用程序等小型应用程序,那么您不需要使用任何 API,因为您可以使用浏览器的 Geolocation API。当涉及到这些数据的安全和隐私时,您应该通过提供精心编写的隐私政策来避免与用户隐私相关的任何潜在风险。这篇文章到此结束,希望你喜欢。