ASP.NET Core WebApi中简单像素转换跟踪实现

像素跟踪虽然是最早用于跟踪营销转换的方法,但它仍然被广泛使用,像Facebook这样的大公司仍然将其视为跟踪网页转换的方法之一。
由于它的简单性,通过像素方法的跟踪转换仍然被广泛使用。它不需要任何复杂的客户端实现,因为它确保它将在几乎所有可以加载图像的浏览器上执行。它由页面上的一个简单的img标记组成,该标记的src属性指向跟踪端点。端点从HTML页面呈现上的图像标记发起的GET请求中接收参数,并将参数发送到后端。作为回报,后端发送图像内容,通常是1x1像素透明PNG或GIF内容。
像素的典型样本将是这样的:
<img src="9102 hello i love uuu" alt="" width="1" height="1" />

由于它是一个简单的GET请求,而不是AJAX调用,因此您无需在后端端启用CORS或其他任何东西,因此使用非常简单方便。跟踪的逻辑在服务器端,因此我们现在将重点关注如何从请求中获取大部分数据并使用1x1像素图像进行响应。
所有请求的共同点是使用图像内容进行响应,因此我们将首先执行此操作。我们首先需要的是图像内容,但如果我们在每次请求时继续从磁盘加载图像,这会损害我们的响应速度,因此可能会减慢客户端浏览器中的页面加载速度。
出于这个原因,我决定将appsettings.json中的图像内容保留为序列化的base64图像内容。此内容加载到单个字节数组,然后在每个控制器操作请求上提供相同的字节数组实例。因此,让我们首先将1x1pixel透明图像存储在配置中。
{
"Response": {
"PixelContentBase64": "R0lGODlhAQABAPcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAABAAEAAAgEAP8FBAA7",
"PixelContentType": "image/gif"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
接下来是创建一个从配置中读取的图像内容的字节数组。这是在ConfigureServices方法的Startup.cs中完成的
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; namespace DotnetCorePixelSample
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<FileContentResult>(new FileContentResult(
Convert.FromBase64String(this.Configuration.GetValue<String>("Response:PixelContentBase64")),
this.Configuration.GetValue<String>("Response:PixelContentType")
)); services.AddMvc();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc();
}
}
}
在加载图像的字节数组内容后,我们将其存储在 FileContentResult类实例中,该实例将用于从像素跟踪WebAPI操作返回的响应。由于它是单音,因此每个请求都会反复使用相同的实例,而不会在请求中添加任何其他处理。
现在还剩下什么,因为我们从Startup中配置的DI注入的内容是收集数据。这是通过访问QueryString参数和Header值在控制器操作中完成的,这些参数是每个请求的一部分。
由于我们不需要等待数据存储完成,我们可以将其包装在Task中并立即返回图像响应。这是一个性能改进,可能导致整个页面在客户端执行不良。
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Primitives; namespace DotnetCorePixelSample.Controllers
{
[Route("[controller]")]
[ApiController]
public class TrackController : ControllerBase
{
readonly FileContentResult pixelResponse; public TrackController(FileContentResult pixelResponse)
{
this.pixelResponse = pixelResponse;
} public IActionResult get()
{
var parameters = Request.Query.Keys.ToDictionary(k => k, k => Request.Query[k]); var headers = Request.Headers.Keys.ToDictionary(k => k, k => Request.Query[k]); Task.Factory.StartNew((data) =>
{
var dataDictionary = data as IDictionary<string, StringValues>;
}, parameters.Union(headers).ToDictionary(k=>k.Key, v=>v.Value)).ConfigureAwait(false);
return pixelResponse;
}
}
}
存储数据与此逻辑无关,您可以使用任何存储来保存收集的数据。
ASP.NET Core WebApi中简单像素转换跟踪实现的更多相关文章
- ASP.NET Core WebAPI中的分析工具MiniProfiler
介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...
- Asp.Net Core WebApi中接入Swagger组件(初级)
开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...
- .NET Core:在ASP.NET Core WebApi中使用Cookie
一.Cookie的作用 Cookie通常用来存储有关用户信息的一条数据,可以用来标识登录用户,Cookie存储在客户端的浏览器上.在大多数浏览器中,每个Cookie都存储为一个小文件.Cookie表示 ...
- ASP.NET Core WebAPI中使用JWT Bearer认证和授权
目录 为什么是 JWT Bearer 什么是 JWT JWT 的优缺点 在 WebAPI 中使用 JWT 认证 刷新 Token 使用授权 简单授权 基于固定角色的授权 基于策略的授权 自定义策略授权 ...
- ASP.NET Core WebApi中使用FluentValidation验证数据模型
原文链接:Common features in ASP.NET Core 2.1 WebApi: Validation 作者:Anthony Giretti 译者:Lamond Lu 介绍 验证用户输 ...
- Asp.Net Core WebAPI中启用XML格式数据支持
因为XML是一种非常常用的数据格式,所以Asp.Net core提供了非常便利的方式来添加对XML格式的支持 只需要在IOC注册Controller服务的后面跟上.AddXmlDataContract ...
- ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- .NET Core WebApi中实现多态数据绑定
什么是多态数据绑定? 我们都知道在ASP.NET Core WebApi中数据绑定机制(Data Binding)负责绑定请求参数, 通常情况下大部分的数据绑定都能在默认的数据绑定器(Binder)中 ...
- ASP.NET Core WebApi使用Swagger生成api
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
随机推荐
- Java 读书笔记 (六) 引用类型
Java里使用long类型的数据要在数值后面加上L,否则会作为整型解析. 引用类型 引用类型是一个对象类型,它的值是指向内存空间的引用,就是地址, 所指向的内存中保存着变量所表示的一个值或一组值. i ...
- python高级编程1
1.如何在列表,字典,集合中根据条件筛选数据? 如: 过滤列表[3, 9, -1, 10, 20, -2...]中的负数 筛出字典{‘小明’:70, 'Jim':88,'Tom':98...}中值高于 ...
- Tomcat 优化方案 和 配置详解(转)
转自 Tomcat 优化方案 和 配置详解 http://201605130349.iteye.com/blog/2298985 Server.xml配置文件用于对整个容器进行相关的配置. <S ...
- Dubbo中Directory解析
Directory代表多个Invoker,可以把它看成List Directory接口 Directory接口继承了Node接口: 1234567 public interface Directory ...
- BZOJ_4196_[Noi2015]软件包管理器_树链剖分
BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...
- BZOJ_2561_最小生成树_最小割
BZOJ_2561_最小生成树_最小割 题意: 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条 ...
- MATLAB——画图(经典)
今天我发现一个非常奇怪的事情,如果你喜欢一样东西或者说是要干一件事,并不一定要把它所在领域的所有都做好, 只要做好你喜欢的就可以了,正如现在的我,突然想学习MATLAB(想画图)那么你只要把一些基础的 ...
- TensorFlow之CNN:运用Batch Norm、Dropout和早停优化卷积神经网络
学卷积神经网络的理论的时候,我觉得自己看懂了,可是到了用代码来搭建一个卷积神经网络时,我发现自己有太多模糊的地方.这次还是基于MINIST数据集搭建一个卷积神经网络,首先给出一个基本的模型,然后再用B ...
- MySQL · 引擎特性 · 临时表那些事儿
前言 相比于普通的用户数据表,MySQL/InnoDB中的临时表,大家应该会陌生很多.再加上不同的临时表创建的时机和创建的位置都不固定,这也进一步加大神秘感.最让人捉摸不透的是,临时表很多时候会先创建 ...
- MIP 组件库升级公告
背景 为了方便广大开发者们更好地使用组件,现对 MIP 组件库统一进行升级,升级后将分为通用组件和自定义组件两类,方便开发. 通用组件,即考虑了组件通用性方便所有开发者参考使用的组件,将存放于 mip ...