精华内容
下载资源
问答
  • (java)web在浏览器端如何获取一个唯一设备标识,可以使用JS flash等方法, 不受浏览器限制(所以不能通过activeX获取mac地址的方法), fingerprintJS/fingerprintJS2、canvas获取的是浏览器指纹,换浏览器就变,...
  • 这里的fingerprint不是uni-app的指纹模块,是一个使用javascript开发的设备指纹采集器,通过这个库可以定位正在使用的浏览器具备的特征唯一标识。如系统字体、屏幕分辨率、浏览器插件,就算使用浏览器的隐私窗口模式...

    前言:

            这里的fingerprint不是uni-app的指纹模块,是一个使用javascript开发的设备指纹采集器,通过这个库可以定位正在使用的浏览器具备的特征唯一标识。如系统字体、屏幕分辨率、浏览器插件,就算使用浏览器的隐私窗口模式也无法匿名。

     

    优缺点:

            因为web无法像移动端可以获取IEMI或者IDFA,并且想或者网卡的Mac也是很难。所以要做一些游客类的精准推送,广告投放等等就变得不太简单。多数人的做法在前端生成UUID存入localstorage,虽然这个是以文件的形式存入电脑中,但是因为也是客户端所以被删除的可能性也大,在删除的情况下UUID也就重新生成。

            而浏览器指纹是当前的浏览器的唯一标识,无关缓存与文件存储,在不更换浏览器下是可以标识设备的唯一。然而,因为是浏览器指纹,所以只要更改相应参数,如插件,调整UA都会产生新的浏览器指纹。
        

     

     

    解决方法:

            将浏览器指纹和localstorage结合使用,在storage中没有值的时候就获取浏览器指纹存入,后面如果不删除的情况,无论怎么更改UA,同一浏览器的标识都只有一个。

     

    安装方式:

    1. CDN: //cdn.jsdelivr.net/npm/fingerprintjs2@<VERSION>/dist/fingerprint2.min.js or https://cdnjs.com/libraries/fingerprintjs2
    2. Bower: bower install fingerprintjs2
    3. NPM: npm install fingerprintjs2
    4. Yarn: yarn add fingerprintjs2

     

    编码使用:

        由于要在uni-app中使用,一般是通过export命令将函数抛出,然后才能在其他的组件中使用import命令,所以就需要对fingerprint2.js进行改造,引入的文件也尽量不要放在组件文件夹下,项目根目录新建即可,原来的代码如下。

     

    1. 首部就需要加入

    var Fingerprint2 = (function(name, context, definition) { // ###代码   })('Fingerprint2', this, function() { // ##还是代码  })
    
    
    
    
    

     

    2. 尾部加入

    export { Fingerprint2 }
    
    
    
    
    

     

    3. 组件中引入

    import uuid from '../library/uuid.js';
    import Fingerprint2 from '../library/fingerprint2.js';
    
    
    
    
    

     

    4. 业务功能部分: 判断storage,没有就取指纹存入,指纹不支持取uuid函数生成。

    const guid = uni.getStorageSync('uuid');
    
    if (!guid) {
    	Fingerprint2.get(function(components) {
    	  const values = components.map(function(component,index) {
    		if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
    		  return component.value.replace(/\bNetType\/\w+\b/, '')
    		}
    		return component.value
    	  })
    	  
    	  const murmur = Fingerprint2.x64hash128(values.join(''), 31)
    	  
    	  if (!murmur) {
    		  murmur = uuid.guid2();
    	  }
    	  
    	  uni.setStorageSync('uuid', murmur);
    	})
    }
    
    
    
    
    

     

    5. 前端uuid生成类

    class uuid {
    	
    	uuid() {
    		var s = [];
    		var hexDigits = "0123456789abcdef";
    		for (var i = 0; i < 36; i++) {
    			s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    		}
    		s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    		s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    		s[8] = s[13] = s[18] = s[23] = "-";
    	
    		var uuid = s.join("");
    		return uuid;
    	}
    	guid() {
    		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    			var r = Math.random() * 16 | 0,
    				v = c == 'x' ? r : (r & 0x3 | 0x8);
    			return v.toString(16);
    		});
    	}
    	guid2() {
    		function S4() {
    			return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    		}
    		return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
    	}
    	
    	uuid2(len, radix) {
    		var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    		var uuid = [],
    			i;
    		radix = radix || chars.length;
    	
    		if (len) {
    			// Compact form
    			for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    		} else {
    			// rfc4122, version 4 form
    			var r;
    	
    			// rfc4122 requires these characters
    			uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    			uuid[14] = '4';
    	
    			// Fill in random data.  At i==19 set the high bits of clock sequence as
    			// per rfc4122, sec. 4.1.5
    			for (i = 0; i < 36; i++) {
    				if (!uuid[i]) {
    					r = 0 | Math.random() * 16;
    					uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
    				}
    			}
    		}
    	
    		return uuid.join('');
    	}
    	
    }
    
    export default new uuid();

     

    展开全文
  • 设备指纹学习

    2020-05-18 17:16:58
    设备ID就相当于这个设备的指纹,不论这个设备使用何种浏览器、何种应用或是在何地,都能够唯一标识设备。 二、分类   设备指纹可以分为主动式、被动式以及混合式设备指纹。 主动式:   在Web、APP嵌入SDK...

    展开
    一、定义
      设备指纹是登录网页或者APP时后台记录的登录设备的指纹,可以准确识别该设备是否曾经登录过。
      通过在网站或者移动端嵌入设备指纹SDK/JS,可以获取操作设备的多重属性,为每一个操作设备建立一个全球唯一的设备ID。该设备ID就相当于这个设备的指纹,不论这个设备使用何种浏览器、何种应用或是在何地,都能够唯一标识该设备。

    二、分类
      设备指纹可以分为主动式、被动式以及混合式设备指纹。

    主动式:
      在Web、APP嵌入SDK或者JS,主动收集与设备相关的信息和特征。
      由于不同生态的平台对用户隐私数据的开放权限不同,所以这种方式在不同的浏览器、Web和APP之间会生成不同的设备指纹ID,使得设备指纹在反欺诈中的对抗性较弱。

    被动式:
      在终端设备与服务器通信的过程中,从数据报文的OSI七层协议中,提取出该终端设备的OS、协议栈和网络状态相关的特征集,并结合机器学习算法以标识和跟踪具体的终端设备。
      这种方式不必在设备终端上嵌入SDK或者JS,其所需要的设备特征都是从终端设备发送过来的数据报文中提取。可以解决不同浏览器、Web和APP之间的关联问题。但由于需要使用机器学习技术构建设备指纹分类算法模型,具有较高的技术壁垒,因而还处于推广起步阶段。

    混合式:
      即既有主动采集部分,又有服务端算法生成部分。
      同一浏览器、Web和APP内部使用主动式设备指纹技术,不同浏览器、Web和APP内部使用被动式设备指纹技术。克服了主动式设备指纹和被动式设备指纹技术各自的固有的缺点。

    三、采集要素
      采集要素即设备中的硬件本身信息以及软件设置信息。常见的要素示例如下:

    IMEI:International Mobile Equipment Identity,存储与手机里的国际移动设备标识串号。
    IDFA:Identifier For Advertising,iOS独有的广告标识符。
    UDID:Unique Device Identifier,唯一设备标识码。
    MEID号, 移动设备识别码(Mobile Equipment Identifier)是CDMA手机的身份识别码,也是每台CDMA手机或通讯平板唯一的识别码。

      对反欺诈比较有意义的有注册设备指纹、登录设备指纹、授信设备指纹、提现设备指纹,不同的变量采用一定的算法加密之后会形成不同的设备指纹。常用的设备信息相关变量如下,图片转自fal金科应用研究院如何从手机上的设备指纹做风控?


    四、应用场景
      防垃圾注册、防撞库、防薅羊毛、反刷单、精准营销、支付反欺诈、授信反欺诈、用户画像分析、复杂关系网络等,涉及领域电商、支付、信贷等。
      下面举两个实际例子:

    场景一:
      黑产发现某贷款平台拉新活动的漏洞,进行批量注册,未修改设备参数。
    防范策略:
      平台通过短期内多人共用设备ID,判断遭受黑产攻击,进而在授信或提现环节阻断其交易。
      单一通过设备指纹并不能完全防住黑产从业者,但可以极大提高黑产和恶意欺诈、骗贷、中介恶意包装等作案成本。比如黑产为了防止被设备指纹规则拦截,需要养号等。

    场景二:
      中介远程操作帮客户申请贷款,注册、登录、OCR及活体检测环节由客户本人操作,但资料填写及最终提交授信由中介操作。
    防范策略:
      通过中介的操作行为,可判断在同一次授信过程中,有两次登录APP行为,且有两个设备指纹ID,最终确定用户此次授信非本人申请的嫌疑很大。

      关于设备指纹的反欺诈策略,大致如下图,转自设备指纹反欺诈策略汇总


    五、其它
      黑产会通过改机软件或模拟器修改设备参数、定位、IP等信息,如果上层设置指纹获取的参数是伪造的,那么生成的设备指纹自然也是无效的。所以好的设备指纹生成技术,应能够识别系统异常环境。比如黑产常见的改机框架、改机软件、伪装软件等,设备指纹都一定要做到针对性的识别。只有确定当前的系统环境没有异常,设备ID才是可信、可用的。成熟的设备指纹产品,可以识别虚拟机、模拟器、以及代理侦测。好的设备指纹可以从以下几个方面来考量:

    准确性-准确率高,不同设备生成的设备指纹保证不会重复,确保设备指纹生成的唯一性。个人的常用设备总是有限的,一段时间内一般不会超过5个以上。
    稳定性-设备系统升级或少量参数变更,设备指纹码不会发生变更。
    生成率-即设备覆盖率,确保各种设备载体都能生成设备指纹唯一码。
    安全性-不会再网络传输中杯篡改、注入导致生成设备伪码。
    六、参考文章
    如何从手机上的设备指纹做风控?
    设备指纹反欺诈策略汇总
    设备指纹详解
     

    展开全文
  • 设备指纹学习笔记

    2021-02-02 15:34:54
    设备ID就相当于这个设备的指纹,不论这个设备使用何种浏览器、何种应用或是在何地,都能够唯一标识设备。 二、分类  设备指纹可以分为主动式、被动式以及混合式设备指纹。 主动式:  在Web、APP嵌入SDK或者...

    一、定义

     设备指纹是登录网页或者APP时后台记录的登录设备的指纹,可以准确识别该设备是否曾经登录过。
     通过在网站或者移动端嵌入设备指纹SDK/JS,可以获取操作设备的多重属性,为每一个操作设备建立一个全球唯一的设备ID。该设备ID就相当于这个设备的指纹,不论这个设备使用何种浏览器、何种应用或是在何地,都能够唯一标识该设备。

    二、分类

     设备指纹可以分为主动式、被动式以及混合式设备指纹。

    主动式:
     在Web、APP嵌入SDK或者JS,主动收集与设备相关的信息和特征。
     由于不同生态的平台对用户隐私数据的开放权限不同,所以这种方式在不同的浏览器、Web和APP之间会生成不同的设备指纹ID,使得设备指纹在反欺诈中的对抗性较弱。

    被动式:
     在终端设备与服务器通信的过程中,从数据报文的OSI七层协议中,提取出该终端设备的OS、协议栈和网络状态相关的特征集,并结合机器学习算法以标识和跟踪具体的终端设备。
     这种方式不必在设备终端上嵌入SDK或者JS,其所需要的设备特征都是从终端设备发送过来的数据报文中提取。可以解决不同浏览器、Web和APP之间的关联问题。但由于需要使用机器学习技术构建设备指纹分类算法模型,具有较高的技术壁垒,因而还处于推广起步阶段。

    混合式:
     即既有主动采集部分,又有服务端算法生成部分。
     同一浏览器、Web和APP内部使用主动式设备指纹技术,不同浏览器、Web和APP内部使用被动式设备指纹技术。克服了主动式设备指纹和被动式设备指纹技术各自的固有的缺点。

    三、采集要素

     采集要素即设备中的硬件本身信息以及软件设置信息。常见的要素示例如下:

    • IMEI:International Mobile Equipment Identity,存储与手机里的国际移动设备标识串号。
    • IDFA:Identifier For Advertising,iOS独有的广告标识符。
    • UDID:Unique Device Identifier,唯一设备标识码。
    • MEID号, 移动设备识别码(Mobile Equipment Identifier)是CDMA手机的身份识别码,也是每台CDMA手机或通讯平板唯一的识别码。

     对反欺诈比较有意义的有注册设备指纹、登录设备指纹、授信设备指纹、提现设备指纹,不同的变量采用一定的算法加密之后会形成不同的设备指纹。常用的设备信息相关变量如下,图片转自fal金科应用研究院如何从手机上的设备指纹做风控?

    四、应用场景

     防垃圾注册、防撞库、防薅羊毛、反刷单、精准营销、支付反欺诈、授信反欺诈、用户画像分析、复杂关系网络等,涉及领域电商、支付、信贷等。
     下面举两个实际例子:

    场景一:
     黑产发现某贷款平台拉新活动的漏洞,进行批量注册,未修改设备参数。
    防范策略:
     平台通过短期内多人共用设备ID,判断遭受黑产攻击,进而在授信或提现环节阻断其交易。
     单一通过设备指纹并不能完全防住黑产从业者,但可以极大提高黑产和恶意欺诈、骗贷、中介恶意包装等作案成本。比如黑产为了防止被设备指纹规则拦截,需要养号等。

    场景二:
     中介远程操作帮客户申请贷款,注册、登录、OCR及活体检测环节由客户本人操作,但资料填写及最终提交授信由中介操作。
    防范策略:
     通过中介的操作行为,可判断在同一次授信过程中,有两次登录APP行为,且有两个设备指纹ID,最终确定用户此次授信非本人申请的嫌疑很大。

     关于设备指纹的反欺诈策略,大致如下图,转自设备指纹反欺诈策略汇总

    五、其它

     黑产会通过改机软件或模拟器修改设备参数、定位、IP等信息,如果上层设置指纹获取的参数是伪造的,那么生成的设备指纹自然也是无效的。所以好的设备指纹生成技术,应能够识别系统异常环境。比如黑产常见的改机框架、改机软件、伪装软件等,设备指纹都一定要做到针对性的识别。只有确定当前的系统环境没有异常,设备ID才是可信、可用的。成熟的设备指纹产品,可以识别虚拟机、模拟器、以及代理侦测。好的设备指纹可以从以下几个方面来考量:

    1. 准确性-准确率高,不同设备生成的设备指纹保证不会重复,确保设备指纹生成的唯一性。个人的常用设备总是有限的,一段时间内一般不会超过5个以上。
    2. 稳定性-设备系统升级或少量参数变更,设备指纹码不会发生变更。
    3. 生成率-即设备覆盖率,确保各种设备载体都能生成设备指纹唯一码。
    4. 安全性-不会再网络传输中杯篡改、注入导致生成设备伪码。

    六、参考文章

    1. 如何从手机上的设备指纹做风控?
    2. 设备指纹反欺诈策略汇总
    3. 设备指纹详解
    展开全文
  • 这些标签可用于唯一标识它们所附着的物品,以便在供应链,制造,资产跟踪和访问控制应用中提供位置和时间证明。 该软件内置于Node.js中,可以在Raspberry Pi 2或3上运行。 它使用MFRC522 RFID阅读器硬件扫描附近的...
  • 笔记Node.js 02

    2020-10-28 20:44:55
    Node.js 02 能够知道B/S软件体系结构 能够搭建Web服务器 能够使用获取GET、POST参数的方式获取参数 能够掌握如何制作路由 ...互联网中设备唯一标识。 IP是Internet Protocol Address的简写,代表互联

    Node.js 02

    能够知道B/S软件体系结构
    能够搭建Web服务器
    能够使用获取GET、POST参数的方式获取参数
    能够掌握如何制作路由
    能够知道同步异步的概念
    能够知道回调函数的概念

    1. 服务器端基础概念

    1.1 网站的组成

    网站应用程序主要分为两大部分:客户端和服务器端。
    Node网站服务器
    能够提供网站访问服务的机器就是网站服务器,它能够接收客户端的请求,能够对请求做出响应。
    在这里插入图片描述

    1.3 IP地址

    互联网中设备的唯一标识。
    IP是Internet Protocol Address的简写,代表互联网协议地址.

    1.4 域名

    由于IP地址难于记忆,所以产生了域名的概念,所谓域名就是平时上网所使用的网址。
    http://www.itheima.com => http://124.165.219.100/
    虽然在地址栏中输入的是网址, 但是最终还是会将域名转换为ip才能访问到指定的网站服务器。

    1.5 端口

    端口是计算机与外界通讯交流的出口,用来区分服务器电脑中提供的不同的服务。
    在这里插入图片描述

    1.6 URL

    统一资源定位符,又叫URL(Uniform Resource Locator),是专为标识Internet网上资源位置而设的一种编址方式,我们平时所说的网页地址指的即是URL。
    URL的组成
    传输协议://服务器IP或域名:端口 /资源所在位置标识
    http://www.itcast.cn /news/20181018/09152238514.html
    http:超文本传输协议,提供了一种发布和接收HTML页面的方法。

    1.7 开发过程中客户端和服务器端说明

    在开发阶段,客户端和服务器端使用同一台电脑,即开发人员电脑。
    开发人员电脑:客户端 (浏览器),服务器端(Node)
    本机域名:localhost
    本地IP :127.0.0.1

    2. 创建web服务器

     // 引用系统模块
      const http = require('http');
      // 创建web服务器
     const app = http.createServer();
      // 当客户端发送请求的时候 req请求, res响应
     app.on('request', (req, res) => {
            //  响应
           res.end('<h1>hi, user</h1>');
     });
      // 监听3000端口
     app.listen(3000);
     console.log('服务器已启动,监听3000端口,请访问 localhost:3000')
    

    3. HTTP协议

    3.1 HTTP协议的概念

    超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)
    规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准。
    在这里插入图片描述

    3.2 报文

    在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。
    在这里插入图片描述

    在这里插入图片描述

    3.3 请求报文

    1. 请求方式 (Request Method)

    GET 请求数据
    POST 发送数据

    2. 请求地址 (Request URL)]
    app.on('request', (req, res) => {
        req.headers  // 获取请求报文
        req.url      // 获取请求地址
        req.method   // 获取请求方法
    });
    

    -----------获取请求的方式-------------

    
    // 用于创建网站服务器的模块
    const http = require('http');
    // app对象就是网站服务器对象
    const app = http.createServer();
    // 当客户端有请求来的时候
    app.on('request', (req, res) => {
        // 获取请求方式
        // req.method
        console.log(req.method);  
        if (req.method == 'POST') {
            res.end('post')
        } else if (req.method == 'GET') {
            res.end('get')
        }
     });
        //监听端口
        app.listen(3000);
        console.log('网站服务器启动成功'));
    

    POST一般用表单
    在这里插入图片描述
    在这里插入图片描述

    -----------请求地址-------------
    req.url 获取请求地址

    // 用于创建网站服务器的模块
    const http = require('http');
    // app对象就是网站服务器对象
    const app = http.createServer();
    // 当客户端有请求来的时候
    app.on('request', (req, res) => {
    // 用于处理url地址
    const url = require('url');
    // 获取请求地址
    // req.url
    console.log(req.url);
    
    if(req.url == '/index' || req.url =='/'){
        res.end('welcome to homepage');
    }else if(req.url == '/list'){
        res.end('welcome to listpage');
    }else{
        res.end('not found');
    }
        if (req.method == 'POST') {
            res.end('post')
        } else if (req.method == 'GET') {
            res.end('get')
        }
     });
        //监听端口
        app.listen(3000);
        console.log('网站服务器启动成功'));
    

    -----------请求报文-------------

    
    // 获取请求报文信息
    // req.headers
    console.log(req.headers['accept']);
    
    if(req.url == '/index' || req.url =='/'){
        res.end('welcome to homepage');
    }else if(req.url == '/list'){
        res.end('welcome to listpage');
    }else{
        res.end('not found');
    }
        if (req.method == 'POST') {
            res.end('post')
        } else if (req.method == 'GET') {
            res.end('get')
        }
     });
        //监听端口
        app.listen(3000);
        console.log('网站服务器启动成功'));
    

    在这里插入图片描述

    3.4 响应报文

    1. HTTP状态码

    200 请求成功
    404 请求的资源没有被找到
    500 服务器端错误
    400 客户端请求有语法错误

    writeHead是一个响应报文处理方法,text/plain是纯文本,h2标签会原封不动书写出来
    在这里插入图片描述
    在这里插入图片描述

    text/html
    在这里插入图片描述
    在这里插入图片描述

    有中文时需要写charset=utf8
    在这里插入图片描述

    2. 内容类型

    text/html
    text/css
    application/javascript
    image/jpeg
    application/json

    app.on('request', (req, res) => {
        // 设置响应报文
        res.writeHead(200, {        
        'Content-Type': 'text/html;charset=utf8‘
        });
    });
    

    4. HTTP请求与响应处理

    4.1 请求参数

    客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作。

    4.2 GET请求参数

    参数被放置在浏览器地址栏中,
    例如:http://localhost:3000/?name=zhangsan&age=20
    参数获取需要借助系统模块url,url模块用来处理url地址

    const http = require('http');
    // 导入url系统模块 用于处理url地址
    const url = require('url');
    const app = http.createServer();
    app.on('request', (req, res) => {
        // 将url路径的各个部分解析出来并返回对象
            // true 代表将参数解析为对象格式
            //parse为解析
        let {query} = url.parse(req.url, true);
        console.log(query);
    });
    app.listen(3000);
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    利用pathname
    在这里插入图片描述
    在这里插入图片描述

    
    // 用于创建网站服务器的模块
    const http = require('http');
    // 用于处理url地址
    const url = require('url');
    // app对象就是网站服务器对象
    const app = http.createServer();
    // 当客户端有请求来的时候
    app.on('request', (req, res) => {
        // 获取请求方式
        // req.method
        // console.log(req.method);
        
        // 获取请求地址
        // req.url
        // console.log(req.url);
        
        // 获取请求报文信息
        // req.headers
        // console.log(req.headers['accept']);
        
        res.writeHead(200, {
            'content-type': 'text/html;charset=utf8'
        });
        console.log(req.url);
        // 1) 要解析的url地址
        // 2) 将查询参数解析成对象形式
        let { query, pathname } = url.parse(req.url, true);
        console.log(query.name)
        console.log(query.age)
        if (pathname == '/index' || pathname == '/') {
            res.end('<h2>欢迎来到首页</h2>');
        }else if (pathname == '/list') {
            res.end('welcome to listpage');
        }else {
            res.end('not found');
        }
        
        if (req.method == 'POST') {
            res.end('post')
        } else if (req.method == 'GET') {
            res.end('get')
        }
        // res.end('<h2>hello user</h2>');
    });
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    

    4.3 POST请求参数

    参数被放置在请求体中进行传输
    获取POST参数需要使用data事件和end事件
    使用querystring系统模块将参数转换为对象格式

     // 导入系统模块querystring 用于将HTTP参数转换为对象格式
     const querystring = require('querystring');
     app.on('request', (req, res) => {
         let postData = '';
         // 监听参数传输事件
         req.on('data', (chunk) => postData += chunk;);
         // 监听参数传输完毕事件
         req.on('end', () => { 
             console.log(querystring.parse(postData)); 
         }); 
     });
    

    POST请求参数是在请求报文中传输,GET的请求参数是在地址栏中传输
    在这里插入图片描述

    Form Data存储的就是POST请求参数
    在这里插入图片描述

    GET和POST的请求参数是一样的,不过GET放在上面的地址栏上,POST放在下面
    在这里插入图片描述

    
    // 用于创建网站服务器的模块
    const http = require('http');
    // app对象就是网站服务器对象
    const app = http.createServer();
    // 处理请求参数模块
    const querystring = require('querystring');
    // 当客户端有请求来的时候
    app.on('request', (req, res) => {
        // post参数是通过事件的方式接受的
        // data 当请求参数传递的时候出发data事件
        // end 当参数传递完成的时候出发end事件
        
        let postParams = '';
        req.on('data', params => {
            postParams += params;
        });
        req.on('end', () => {
            console.log(querystring.parse(postParams));
        });
        res.end('ok');
    });
    // 监听端口
    app.listen(3000);
    console.log('网站服务器启动成功');
    
    
    

    4.4 路由

    http://localhost:3000/index
    http://localhost:3000/login
    路由是指客户端请求地址与服务器端程序代码的对应关系。简单的说,就是请求什么响应什么。

     // 当客户端发来请求的时候
     app.on('request', (req, res) => {
        // 获取客户端的请求路径
        let { pathname } = url.parse(req.url);
        if (pathname == '/' || pathname == '/index') {
            res.end('欢迎来到首页');
        } else if (pathname == '/list') {
            res.end('欢迎来到列表页页');
        } else {
           res.end('抱歉, 您访问的页面出游了');
        }
    });
    

    在这里插入图片描述

    // 1.引入系统模块http
    // 2.创建网站服务器
    // 3.为网站服务器对象添加请求事件
    // 4.实现路由功能
    //  1.获取客户端的请求方式
    //  2.获取客户端的请求地址
    const http = require('http');
    const url = require('url');
    const app = http.createServer();
    app.on('request', (req, res) => {
        // 获取请求方式
        const method = req.method.toLowerCase();
        // 获取请求地址
        const pathname = url.parse(req.url).pathname;
        res.writeHead(200, {
            'content-type': 'text/html;charset=utf8'
        });
        if (method == 'get') {
            if (pathname == '/' || pathname == '/index') {
                res.end('欢迎来到首页')
            }else if (pathname == '/list') {
                res.end('欢迎来到列表页')
            }else {
                res.end('您访问的页面不存在')
            }
        }else if (method == 'post') {
        }
    });
    app.listen(3000);
    console.log('服务器启动成功')
    

    在这里插入图片描述

    4.5 静态资源

    服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,例如CSS、JavaScript、image文件。

    
    const http = require('http');
    const url = require('url');
    const path = require('path');
    const fs = require('fs');
    const mime = require('mime');
    const app = http.createServer();
    app.on('request', (req, res) => {
        // 获取用户的请求路径
        let pathname = url.parse(req.url).pathname;
        pathname = pathname == '/' ? '/default.html' : pathname;
        // 将用户的请求路径转换为实际的服务器硬盘路径
        let realPath = path.join(__dirname, 'public' + pathname);
        //根据路径返回该资源的类型
        let type = mime.getType(realPath)
        // 读取文件
        fs.readFile(realPath, (error, result) => {
            // 如果文件读取失败
            if (error != null) {
                res.writeHead(404, {
                    'content-type': 'text/html;charset=utf8'
                })
                res.end('文件读取失败');
                return;
            }
            res.writeHead(200, {
                'content-type': type
            })
            res.end(result);
        });
    });
    app.listen(3000);
    console.log('服务器启动成功')
    
    

    下载一个mine插件 解决html中的a标签href会链接到图片、文字等链接,根据文件请求的类型设置对应的类型
    在这里插入图片描述

    4.6 动态资源

    相同的请求地址不同的响应资源,这种资源就是动态资源。
    http://www.itcast.cn/article?id=1
    http://www.itcast.cn/article?id=2

    4.7 客户端请求途径

    1. GET方式

    浏览器地址栏
    link标签的href属性
    script标签的src属性
    img标签的src属性
    Form表单提交

    2. POST方式

    Form表单提交

    展开全文
  • 组织唯一标识符(OUI)是一个24位数字,用于唯一标识全球或全球范围内的供应商,制造商或其他组织。 这些是从电气和电子工程师协会(IEEE)注册机构购买的。 它们用作派生标识符的第一部分,以唯一地标识特定的...
  • IPFS使用内容寻址来唯一标识连接所有计算设备的全局命名空间中的每个文件。 它是用于基于内容的去中心化存储的理想解决方案,并且针对进行了优化。 介绍 laravel-ipfs是IPFS HTTP API的简单包装,采用了一种优雅的...
  • Flask应用程序在静态目录中提取CSS来获取Web网页模板的格式,JavaScript和图像文件。该图像目录是在咖啡馆的菜单和标识的文件将被放置。 前端模板 有一个默认模板可以用作所有网页的通用基础。默认模板处理诸如基本...
  • Splunk是一种高扩充性且通用的数据引擎。... 10.5 远程查询Splunk的REST API以获取唯一页面浏览量 278 10.6 创建Python应用程序返回唯一IP地址 280 10.7 创建自定义搜索命令来格式化产品名称 284 10.8 小结 288
  • adb1.0.26包含fastboot.exe

    2019-03-05 15:11:03
    注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。 no device —— 没有设备/模拟器连接。 以上输出显示当前已经连接了...
  • 注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。 no device —— 没有设备/模拟器连接。 以上输出显示当前已经连接了...
  • 0 前言说明 下载说明:由于可执行文件比较大,如有需要请到网盘下载。...百度地图上可以鼠标单击获取经纬度信息,用来更新设备位置。 视频监控面板窗体中任意通道支持拖曳交换,瞬间响应。 封装了百度地图,视图切换,...
  • C#编程经验技巧宝典

    热门讨论 2008-06-01 08:59:33
    115 <br>0193 如何获取应用程序当前执行的路径 116 <br>0194 如何获取当前操作系统的信息 116 <br>0195 如何实现基本数据类型随意转换 116 <br>0196 如何生成全局唯一标识符(GUID) 118 <br>...
  • iPhone开发秘籍(第2版)--详细书签版

    热门讨论 2012-12-11 13:42:25
    2.16 定制Xcode标识 66 2.17 创建自定义Xcode模板 66 2.17.1 覆盖com.yourcompany 67 2.17.2 构建其他模板 67 2.18 并排查看代码 68 2.19 小结 69 第3章 Objective-C训练营 70 3.1 Objective-C编程语言 70 ...
  • iPhone开发秘籍(第2版)--源代码

    热门讨论 2012-12-11 13:51:22
    2.16 定制Xcode标识 66 2.17 创建自定义Xcode模板 66 2.17.1 覆盖com.yourcompany 67 2.17.2 构建其他模板 67 2.18 并排查看代码 68 2.19 小结 69 第3章 Objective-C训练营 70 3.1 Objective-C编程语言 70 ...
  • 和传统的 t-sql书籍不同,本书以独特的 “技巧 ”形式来介绍知识点,涵盖了数据处理(增删改、视图、索引、存储过程、触发器等)、数据应用(web服务、 clr集成、分布式查询等)和数据库配置(主体、安全、数据库...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    超越今天各自为营的 Web 站点 站点站点 站点 把 把把 把 Internet 建成一 建成建成 建成 个 一个一 一个可 可个可 可 以互相交换组件的地方 以互相交换组件的地方以互相交换组件的地方 以...
  • C#微软培训资料

    2014-01-22 14:10:17
    超越今天各自为营的 Web 站点 站点站点 站点 把 把把 把 Internet 建成一 建成建成 建成 个 一个一 一个可 可个可 可 以互相交换组件的地方 以互相交换组件的地方以互相交换组件的地方 以...
  • • 利用TEXT函数格式化设备编号 • 从身份证号码中提取员工的生日信息 • 使用TEXT 函数显示中文格式的年份 • 将数值转换为商业发票中的中文大写金额 • 生成中文大写金额 • 利用CELL 函数取得动态工作表标签名称 ...
  • 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。比如数据量太大之后,往往需要对进行对数据进行分库分表,分库分表后需要有一个唯一 ID 来标识一条数据或消息,数据库的自增 ID 显然不能满足需求。...
  • 唯一的IDs标识数据对象 第十四章. 数据绑定(466) 14.1节. 绑定一个属性 14.2节. 绑定到一个函数 14.3节. 创建一个双向绑定 14.4节. 使用ActionScript来进行数据绑定 14.5节. 链式的属性绑定 14.6节. 使用E4X...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    软件工程ppt 建议没有基础或者兴趣的同学别下载 因为软件工程理解需要耐心和能力 主讲:邱焕耀 经历 华南理工大学,博士,计算机控制 曾任职以下公司: 中国民航信息广州公司(香港上市)技术总监 ...

空空如也

空空如也

1 2
收藏数 26
精华内容 10
关键字:

web获取设备唯一标识