node基本使用,node介绍
本文将与您分享一个实践经验,并介绍在Node中构建位置分析报告API的方法。在本教程结束时,您还将对Node.js中的错误处理和良好的文件结构有更好的了解,希望对您有所帮助!
node.js速度课程简介:进入学习
经纬度定义的位置可以结合其他数据为企业产生洞察,这就是位置分析。
在全球范围内运营的企业在整个价值链中使用位置分析,例如,定位用户、提供服务和投放有针对性的广告。随着社交媒体和移动设备的兴起,位置分析的使用在全球范围内有所增加。
在本教程中,我们将学习如何在Node.js中构建轻量级位置分析报告服务API。在本教程结束时,您将能够为自己的项目构建这种类型的API。您还将对Node.js中的错误处理和良好的文件结构有更好的理解
我们开始吧!
前提条件
继续学习本教程,需要具备以下条件。
熟悉Node.js,Express和GitVisual Studio代码编辑器Heroku账号邮差账号
设置文件结构
首先我们需要设置好我们的文件结构。打开您的终端并创建一个新目录,您将在其中存储项目的所有文件。在您的终端上,键入以下命令,后跟文件夹的名称lars。
Mkdir lars在VS代码编辑器中打开lars工作目录。
代码。您将看到您的VS代码窗口打开。
Visual Studio代码窗口
在Visual Studio中打开您的终端,并运行npm init -y来初始化工作目录。
如果您想在VS代码之外的操作系统的终端中运行这个命令,请导航到lars目录并运行下面的命令。
npinit-y上面的代码自动生成package.json文件。
VS代码显示创建的package.json文件。
在本教程中,我们将使用Express作为依赖项。通过运行以下命令安装Express。
npm快速安装-保存
将Express作为依赖项安装的命令
安装Express后,您会注意到已经创建了一个node_modules文件夹。为了确认您已经安装了Express,请检查您的package.json文件,您将看到Express是作为一个依赖项安装的。
node_modules文件夹被创建,Express被添加到package.json中
我们需要将Express导入到我们的应用程序中,因为它是一个npm模块。在与package.json文件相同的目录中创建一个名为app.js的新文件。
VS代码窗口截图显示app.js已经创建。
在app.js文件中,通过运行以下代码requireExpress。
const express=require( express );
进口快递
现在,调用Express来创建您的应用程序、路由和应用程序将运行的端口。
const app=express();Node.js是模块化的,这意味着它将您的应用程序划分为模块或各种文件,并导出每个文件。我们将使用export关键字来导出应用程序。
module.exports=app
App.js文件
接下来,在与app.js文件相同的目录中创建另一个名为server.js的文件。Require将app.js文件导入server.js文件。
const app=require(。/app’);在与server.js相同的目录中创建一个名为config.env的文件。config.env文件将包含我们的应用程序所需的所有[process . env](https://nodejs.org/dist/latest-v8.x/docs/api/process.html)和我们的应用程序所需的所有键。在config.env文件中,创建一个端口变量,并将端口设置为监听端口8000。
PORT=8000导入应用程序后,在server.js文件中创建一个名为PORT的常量。将它设置为您刚刚创建的端口变量和默认端口3000。
const port=process . env . port 3000;最后,我们将使用。listen()方法将应用程序设置为侦听此端口。
app.listen(port,()={
console.log(`应用程序侦听${port} `)
});
构建路由
每当您访问网络上运行的网页或应用程序时,您都在发出HTTP请求。服务器用来自后台或数据库的数据进行响应,这称为HTTP响应。
当您在web应用程序上创建资源时,您正在调用一个POST请求。类似地,如果您尝试删除或更新Web应用程序上的资源,您将调用删除、修补或更新请求。让我们建立一个路由来处理这些请求。
在工作目录中创建一个名为routes的文件夹,并在其中创建一个名为analyticsRoute.js的文件。要求在analyticsRoute.js文件中表达设置API的路径。
const express=require( express );我们还需要app.js文件中的应用程序模块。
const app=require(./app’);然后,我们创建我们的路线。
常量路由器=express。路由器();最后,我们要导出路由器。
module.exports=路由器;
建立控制器
我们需要为控制器创建一个文件,并将其导入我们的analyticsRoutes文件。首先,在工作目录中创建一个名为controllers的文件夹。
我们的API将使用用户提供的IP地址和坐标来计算距离和位置。我们的请求需要接受这些信息和来自用户的请求。
我们将使用POST请求,因为用户在req.body中。为了保存该信息,我们需要在控制器中有一个fs模块(文件系统)。
处理POST 的请求
在controllers文件夹中创建名为storeController.js的文件。在storeController.js文件中,我们需要导入fs模块和fsPromises.readFile()方法来处理返回的promise,也就是用户的IP地址和坐标。
要安装fs模块,请在工作目录中打开您的终端并运行以下命令。
NPIFS-SAVE在文件顶部输入以下代码。
const fsp=require(fs )。承诺;
const fs=require( fs );接下来,我们将创建一个控制器来处理POST请求的路由。我们将使用exports关键字并创建一个接受三个参数的异步中间件函数。
Req:表示请求对象res:表示响应对象next:中间件输出后立即调用函数。Post=async (req,res,next)={}现在,我们将把req.body中数据对象的属性保存到reportAnalytics数组中。我们将设置一个Date()对象来保存createdAt键中任何数据的创建日期。
reportAnalytics.push({.req.body,createdAt:new Date()});我们将创建一个名为storeAnalytics.json的文件,并使用JSON.stringify()将reportAnalytics数组的内容保存为一个字符串。
await FSP . writefile(` $ { _ _ dirname }/store analytics . json`,JSON . stringify(report analytics));当用户发出POST请求时,我们需要检查storeAnalytics.json文件是否存在。如果文件存在,我们需要读取它并保存输出。
输出包含一个名为reportFile的常量,它存储读取文件的内容。在reportFile中,使用JSON.parse将文件内容转换为JavaScript对象。
//检查文件是否存在
if(fs . exists sync(` $ { _ _ dirname }/store analytics . JSON `) {
//如果文件存在,读取文件
const report file=await FSP . readfile(` $ { _ _ dirname }/store analytics . JSON `, utf-8 )
//将文件转换为JavaScript对象
reportAnalytics=JSON.parse(报告文件)
}否则{
//如果文件不存在
return(“文件不存在”);
}方法同步检查文件是否存在。它将$ { _ _ dirname }/store analytics . JSON路径作为其单个参数,并指向我们要检查的文件的位置。
我们对reportFile使用await关键字,等待fsp.readFile()方法读取文件的结果。接下来,我们使用($ { _ _ dirname }/store analytics . JSON来指定我们想要读取的文件的路径。我们将编码格式设置为utf-8,这将把从文件中读取的内容转换为字符串。
JSON.parse()将reportFile转换为JavaScript对象,并将其存储在reportAnalytics数组中。else语句块中的代码仅在文件不存在时运行。最后,我们使用return语句,因为我们希望在代码运行后停止函数的执行。
如果文件被成功读取,创建并保存在storeAnalytics.json中,我们需要发送一个响应。我们将使用响应对象(res),这是异步postAnalytics函数的第二个参数。
根据现状(201)。json({
状态:“成功”,
数据:{
消息:“成功获取IP和坐标”
}
})我们将用状态成功和数据信息IP和坐标成功获取来响应。
您的storeController.js文件应该类似于下面的屏幕截图。
处理GET 的请求
我们需要创建另一个控制器文件来处理我们的GET请求。当用户向API发出GET请求时,我们会根据他们的IP地址和坐标计算他们的位置。
在控制器文件夹中创建一个名为fetchController.js的文件。在storeController.js文件中,我们需要require模块和fsPromises.readFile()方法来处理返回的承诺。
const fsp=require(fs )。承诺;
const fs=require( fs );让我们创建一个控制器来处理GET请求的路由。我们将使用类似的中间件功能和参数来处理上述POST请求。
Exports.getAnalytics=async (req,res,next)={}在getAnalytics中间件中,输入以下代码以从请求的查询中获取IP地址。
const { ip }=req.query现在,创建一个空数组来存储req.body的内容
let report analytics=[];正如我们之前所做的,我们需要检查storeAnalytics.json文件是否存在。如果文件存在,我们将使用reportFile上的JSON.parse将文件内容转换成JavaScript对象。
if(fs . exists sync(` $ { _ _ dirname }/store analytics . JSON `) {
const report file=await FSP . readfile(` $ { _ _ dirname }/store analytics . JSON `, utf-8 )
reportAnalytics=JSON.parse(报告文件)
}否则{
return(“文件不存在”);
}现在,我们可以在storeAnalytics.json文件中保存用户的IP地址和坐标。每当用户请求根据提供的坐标计算地理位置时,IP地址将以查询的形式包含在请求中。
现在我们已经从req.query对象中获得了IP地址,我们可以编写代码来检查req.query对象中提供的IP地址是否与storeAnalytics.json文件中存储的IP地址相同。
for(设I=0;ireportAnalytics.lengthi ) {
if (reportAnalytics[i].ip!==ip) {
返回(未找到该IP的坐标);
};
}在上面的代码中,我们使用forloop循环遍历reportAnalytics数组。我们将变量I初始化为0,它表示reportAnalytics数组中当前元素的索引。如果I小于reportAnalytics数组的长度,我们将递增它。
接下来,我们检查reportAnalytics数组的IP地址属性是否等于req.query中提供的IP地址
让我们计算一下仅在最后一个小时存储的IP地址的位置。
const hourAgo=new Date();
hourago . set hours(hourago . get hours()-1);
const get report=report analytics . filter(El=
el.ip===ip新日期(el.createdAt)小时前
)在上面的代码块中,我们创建了一个名为hourAgo的常量,并将其设置为Date对象。我们使用setHours()方法将hourAgo设置为最后一个小时的getHours()-1。
当reportAnalytics文件中的当前IP地址等于或等于req.query中传递的IP地址时,这意味着数据是在最近一小时内创建的。getReport创建一个常量,并将其设置为一个新数组。
创建一个名为coordinatesArray的常量,它将只存储已经保存在getReport数组中的坐标。
const Coordinates Array=get report . map(element=element . Coordinates)接下来,我们需要用坐标计算位置。我们需要遍历coordinatesArray,并通过传入两个保存为坐标的值来计算位置。
设total length=0;
for(设I=0;icoordinatesArray.lengthi ) {
if(I==coordinates array . length-1){
打破;
}
设distance=calculated distance(coordinates array[I],coordina tes array[I 1]);
总长度=距离;
}在上面的代码中,totalLength表示从两个坐标计算的总距离。为了遍历coordinatesArray,我们需要初始化我们的计算结果。将totalLength设置为零,以初始化总距离。
第二行包含我们使用的循环迭代代码。我们用i=0初始化I变量。I变量代表coordinatesArray中当前元素的索引。
IcoordinatesArray.length设置迭代的条件,仅在当前元素的索引小于coordinatesArray的长度时运行。接下来,我们在迭代中增加当前元素的索引,以移动到下一个元素,即
接下来,我们将检查当前元素的索引是否等于数组中最后一个元素的编号。然后,我们暂停迭代代码的执行,转到下一个带有break关键字的代码。
最后,我们创建一个名为calculateDistance的函数,它接受两个参数,即第一个和第二个坐标值(经度和纬度)。我们将在另一个模块中创建calculateDistance,并将其导出到fetchController.js文件中,然后将最终结果保存在初始化的totalLength变量中。
请注意,每个请求都需要一个响应。我们将用一个200的statusCode和一个包含我们将要计算的距离值的JSON来响应。只有当代码成功时,才会显示响应。
研究现状(200)。json ({distance: totallength})您的fetchController.js文件应该类似于以下两个代码块。
FetchController.js文件
fetchController.js文件的续集
建立calculateDistance 函数
在您的工作目录中,创建一个名为utilities的新文件夹,并在其中创建一个名为calculateDistance.js的文件。打开calculateDistance.js文件并添加以下函数。
const calculated distance=(coordinate 1,coordinate2)={
const distance=math . sqrt(math . pow(Number(coordinate 1 . x)-Number(coordinate 2 . x),2)math . pow(Number(coordinate 1 . y)-Number(coordinate 2 . y),2))。
返回距离;
}
module.exports=计算距离;在第一行中,我们创建了一个名为calculateDistance的函数,它有两个参数:coordinate1和coordinate2。它使用下面的等式。
Math.sqrt:数学中的平方根Math.pow:将一个数提升到一个幂():将一个值转换成一个数coordinate1.x:第一个坐标(经度)的第二个值coordinate2.x:第一个坐标(经度)的第一个值。Coordinate1.y:第二个坐标的第二个值(纬度)。Coordinate2.y:第二个坐标的第一个值(纬度)。现在我们已经创建了calculateDistance函数,我们需要将该函数放入fetchController.js文件的代码中。在fs模块后添加以下代码。
const calculateDistance=require(./utilities/calculate distance );
实现错误处理
实现错误处理很重要,这样可以防止我们的代码失败或某个特定的实现无法按设计运行。我们将在开发和生产中添加错误处理。
打开config.env文件,运行NODE_ENV=development,并将环境设置为development。
在controllers文件夹中,创建一个名为errorController.js的新文件。下面的代码片段创建了一个名为sendErrorDev的函数,用于处理开发环境中遇到的错误。
const sendErrorDev=(err,res)={
资源状态(err.statusCode)。json({
状态:err.status
错误:错误,
消息:err.message,
stack: err.stack
});
}我们将创建一个名为sendErrorDev的函数,它接受两个参数,呃表示错误,res表示响应106 .响应。状态接收错误的statusCode,并以数据数据进行响应。
此外,我们将创建一个名为sendErrorProd的函数,它将处理应用程序接口在生产环境中遇到的错误。
const sendErrorProd=(err,res)={
如果(呃。iso操作){
资源状态(err.statusCode).json({
状态:错误状态
消息:错误消息
});
}否则{
console.error(Error ,err);
决议现状(500).json({
状态:"错误",
消息:"出现问题"
})
}
}在你的公用事业文件夹中,创建一个名为阿佩尔罗的文件,并输入以下代码。
类错误扩展错误{
构造函数(消息,状态代码){
超级(消息);
这个。状态代码=状态代码;
这个。status=` $ {状态代码} `。以( 4 )开头?"失败":"错误";
this.isOperational=true
Error.captureStackTrace(这个,这个。建造师);
}
}
module.exports=AppError我们将创建一个名为阿佩尔罗的类,它扩展了错误对象。
然后,我们将创建一个构造函数,它将初始化该类的对象。它接受两个参数,叫做消息和状态码。极好的方法用一个参数调用构造函数,将其传入消息,并获得对构造函数的属性和方法的访问。
接下来,我们将构造函数的状态码属性设置为状态码。我们将构造函数的状态属性设置为任何以四开始的状态码,例如,将404状态码设置为失败或错误。
创建另一个名为catchAsync.js的文件,并在其中添加以下代码。
module.exports=fn={
return (req,res,next)={
fn(请求,结果,下一个)。接住(下一个);
}
}
在控制器文件中添加错误处理
要求阿佩尔罗文件和catchAsync.js文件在你的商店控制器。射流研究…和fetchController.js文件中。将这两条导入语句放在两个文件中的代码顶部。
const catchAsync=require(./utilities/catch async’);
const AppError=require(./utilities/appError’);在商店控制器。射流研究…和fetchController.js文件中,用catchAsync()方法包装你的函数,如下所示。
//对于商店控制器. js文件
出口。post analytics=catch async(async(req,res,next)={.}
//对于fetchController.js文件
出口。get analytics=catch async(async(req,res,next)={.}接下来,在你的fetchController.js文件中,运行阿佩尔罗类。
对于(设I=0;ireportalytics . length I){
if (reportAnalytics[i].ip!==ip) {
返回接下来(新的AppError(没有找到具有该互联网协议(Internet Protocol)的坐标,404));
};
}接下来,在你的商店控制器。射流研究…文件中运行阿佩尔罗类。
如果(fs。exists sync(` $ { _ _ dirname }/store analytics。JSON `) {
const报告文件=等待FSP。readfile(` $ { _ _ dirname }/store analytics。JSON `, utf-8 )
reportAnalytics=JSON.parse(报告文件)
}否则{
返回下一个(新的AppError(文件不存在,404));
}你的商店控制器。射流研究…和fetchController.js文件中的代码应该看起来像下面的截图。
商店控制器。射流研究…文件的屏幕截图
fetchController.js文件第1-32行
fetchController.js文件第33-37行
设置验证
我们需要验证在请求体其中包括互联网协议(互联网协议)地址和坐标的数据,是正确的,而且格式正确。坐标应该至少有两个值,代表经度和纬度。
在公用事业文件夹中,创建一个名为确认的新文件夹。在确认文件夹中,创建一个名为schema.js的文件schema.js文件将包含请求体中提供的任何数据的所需格式。我们将使用[joi](https://www。NPM js。com/package/joi)验证器。
新公共管理安装蔡淳佳在schema.js文件中输入以下代码。
const Joi=require( Joi );
const schema=Joi.object().钥匙({
ip: Joi.string().ip().必需的(),
坐标:Joi.object({
x: Joi.number().必需的(),
y: Joi.number().必需的()
}).必需的()
})
module.exports=schema在上面的代码块中,我们需要验证器并使用它来创建我们的模式。然后,我们将IP地址设置为一个字符串,并通过在请求体中请求IP地址来验证IP地址。
我们将坐标设置为object。我们将表示经度和纬度值的X和Y值都设置为数字,并需要它们以便我们的代码可以运行。最后,我们推导出模式。
在validator文件夹中,创建另一个名为validateIP.js的文件,我们将编写代码来验证IP地址,使用[IS-IP](https://www.npmjs.com/package/IS-IP)NPM包。让我们将这个包导出到我们的代码中。
在validateIP.js文件中,添加以下代码。
const isIp=require( is-IP );
const fsp=require(fs )。承诺;
const fs=require( fs );
exports.validateIP=(req,res,next)={
if(isIp(req.query.ip)!==true) {
返回资源状态(404)。json({
状态:“失败”,
数据:{
消息:“无效IP,未找到。”
}
})
}
next();
}运行以下命令,为我们的API安装必要的依赖项。
m install body-parser CORS dot env express fs is-IP joi mor gan ndb node mon您的app.js文件应该类似于下面的屏幕截图。
App.js文件
在package.json文件的scripts部分下,添加以下代码片段。
start:dev: node server.js ,
Debug: ndb server.js 你的package.json文件应该看起来像下面的截图。
Package.json文件
使用以下代码更新analyticsRoute.js文件。
const express=require( express );
const app=require(./app’);
常量路由器=express。路由器();
const validateIP=require(./utilities/validate IP );
const storeController=require(./controllers/store controller’);
const fetchController=require(./controllers/fetch controller’);
router.route(/analytics )。post(store controller . post analytics)。get(validateIP.validateIP,fetch controller . get analytics);
module.exports=路由器;现在,我们已经完成了我们的位置分析API的构建!现在,让我们测试我们的代码,以确保它的工作。
测试API
我们将使用Postman来测试我们的API。让我们启动API来确保它在我们的终端中运行。
Node server.js您将在终端中看到以下输出。
末端的
我们的API托管在Heroku上,它的最终输出应该如下所示。
结论
区位分析对企业来说是一个很棒的工具。位置允许公司更好地服务于潜在的和现有的客户。
在本教程中,我们学习了构建一个工具来获取IP地址和坐标形式的位置信息,并计算距离。我们在Node.js中设置了文件结构,建立了处理GET和POST请求的路径,添加了错误处理,最后测试了我们的应用程序。
您可以使用在本教程中学到的信息来构建您自己的位置报告API,该API可以根据您自己的业务需求进行定制。
node . js中的postBuild a location analytics reporting API首先出现在LogRocket博客上。
更多关于node的信息,请访问:nodejs教程!上面的文章详细解释了如何在Node中构建轻量级的位置分析报告服务API。请多关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。