像素跟踪虽然是最早用于跟踪营销转换的方法,但它仍然被广泛使用,像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中简单像素转换跟踪实现的更多相关文章

  1. ASP.NET Core WebAPI中的分析工具MiniProfiler

    介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...

  2. Asp.Net Core WebApi中接入Swagger组件(初级)

    开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...

  3. .NET Core:在ASP.NET Core WebApi中使用Cookie

    一.Cookie的作用 Cookie通常用来存储有关用户信息的一条数据,可以用来标识登录用户,Cookie存储在客户端的浏览器上.在大多数浏览器中,每个Cookie都存储为一个小文件.Cookie表示 ...

  4. ASP.NET Core WebAPI中使用JWT Bearer认证和授权

    目录 为什么是 JWT Bearer 什么是 JWT JWT 的优缺点 在 WebAPI 中使用 JWT 认证 刷新 Token 使用授权 简单授权 基于固定角色的授权 基于策略的授权 自定义策略授权 ...

  5. ASP.NET Core WebApi中使用FluentValidation验证数据模型

    原文链接:Common features in ASP.NET Core 2.1 WebApi: Validation 作者:Anthony Giretti 译者:Lamond Lu 介绍 验证用户输 ...

  6. Asp.Net Core WebAPI中启用XML格式数据支持

    因为XML是一种非常常用的数据格式,所以Asp.Net core提供了非常便利的方式来添加对XML格式的支持 只需要在IOC注册Controller服务的后面跟上.AddXmlDataContract ...

  7. ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

  8. .NET Core WebApi中实现多态数据绑定

    什么是多态数据绑定? 我们都知道在ASP.NET Core WebApi中数据绑定机制(Data Binding)负责绑定请求参数, 通常情况下大部分的数据绑定都能在默认的数据绑定器(Binder)中 ...

  9. ASP.NET Core WebApi使用Swagger生成api

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

随机推荐

  1. Java 开发, volatile 你必须了解一下

    上一篇文章说了 CAS 原理,其中说到了 Atomic* 类,他们实现原子操作的机制就依靠了 volatile 的内存可见性特性.如果还不了解 CAS 和 Atomic*,建议看一下我们说的 CAS ...

  2. 比较集合List<T>集合,前后多了哪些数据,少了哪些数据Except

    1.少了哪些数据 private List<int> GetRoleIdListReduce(List<int> roleIdListOld, List<int> ...

  3. Dubbo中暴露服务的过程解析

    dubbo暴露服务有两种情况,一种是设置了延迟暴露(比如delay="5000"),另外一种是没有设置延迟暴露或者延迟设置为-1(delay="-1"): 设置 ...

  4. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  5. 【树形dp】Bzoj3391 [Usaco2004 Dec]Tree Cutting网络破坏

    Description     约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报 复.她打算破坏刚建成的约翰的网络.    约翰的网络是树形的,连接着N(1≤N≤1000 ...

  6. B20J_1297_[SCOI2009]迷路_矩阵乘法

    B20J_1297_[SCOI2009]迷路_矩阵乘法 题意:有向图 N 个节点,从节点 0 出发,必须恰好在 T 时刻到达节点 N-1.总共有多少种不同的路径? 2 <= N <= 10 ...

  7. python使用sqlmap API检测SQL注入

    0x00前言: 大家都知道sqlmap是非常强大的sql注入工具,最近发现他有个sqlmap API,上网查了一下.发现这是 sqlmap的微端.(可以叫做sqlmap在线检测sql注入= =) 0x ...

  8. MYSQL—— year类型的使用与注意点!

    mysql的日期与时间类型:分为time.date.datetime.timestamp.year,主要总结下year的用法: 1.类型支持:year 与 year(4),注意无year(2)的定义方 ...

  9. 已管理员身份从cmd框进入mysql,及常用的简单操作!

    在命令框中操作mysql已管理员的身份进入操作权限较高,已普通用户进入cmd框也可对mysql进行操作,不过一般建议用管理员身份进入. 1.启动MYSQL Notifier 2.已管理员身份进入cmd ...

  10. 循环table 示例

    1.循环table里的某一列 //当前第三列 //注:索引从1开始 $("#tabcardno tr td:nth-child(3)").each(function () { va ...