像素跟踪虽然是最早用于跟踪营销转换的方法,但它仍然被广泛使用,像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. textarea去掉右下角拖拽

    /*去掉textarea右下角三角符号*/ resize : none;

  2. IDEA破解 Intellij IDEA license server 激活(可用)

    激活地址如下图所示: 2018 intellij idea 注册码(亲测可用): C0FHYYCJ22-eyJsaWNlbnNlSWQiOiJDMEZIWVlDSjIyIiwibGljZW5zZWVO ...

  3. 由一条sql语句想到的子查询优化

    摘要:相信大家都使用过子查询,因为使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,比较灵活,我也喜欢用,可最近因为一条包含子查询的select count(*)语句导致点开管理系 ...

  4. 理解、学习与使用 Java 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  5. 关于throw、throws、try--catch的问题

    首先回顾概念 throws表示出现异常的一种可能性,并不一定会发生这些异常 throw则是抛出了异常,执行throw则一定抛出了某种异常 try--catch try语句用大括号{}指定了一段代码,该 ...

  6. Spark学习之Spark SQL

    一.简介 Spark SQL 提供了以下三大功能. (1) Spark SQL 可以从各种结构化数据源(例如 JSON.Hive.Parquet 等)中读取数据. (2) Spark SQL 不仅支持 ...

  7. 死磕 java集合之PriorityBlockingQueue源码分析

    问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...

  8. Bumblebee之负载、限流和故障处理实践

    Bumblebee作为标准HTTP 1.1应用协议的网关,它能作为任何基于HTTP 1.1构建Webapi服务的前置网关.以下通过示例讲述如何用Bumblebee来制作一个asp.net core w ...

  9. 从零单排学Redis【黄金】

    前言 只有光头才能变强 好的,今天我们要上黄金段位了,如果还没经历过青铜和白银阶段的,可以先去蹭蹭经验再回来: 从零单排学Redis[青铜] 从零单排学Redis[白银] 看过相关Redis基础的同学 ...

  10. C#机器学习之判断日报是否合格

    简单来说机器学习的核心步骤在于“获取学习数据:选择机器算法:定型模型:评估模型,预测模型结果”,下面本人就以判断日报内容是否合格为例为大家简单的阐述一下C#的机器学习. 第一步:问题分析 根据需求可以 ...