像素跟踪虽然是最早用于跟踪营销转换的方法,但它仍然被广泛使用,像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. 关于SELinux

    出现背景以及发展历程 SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security Agency」 和SCC(Secu ...

  2. BZOJ_1598_[Usaco2008 Mar]牛跑步_A*

    BZOJ_1598_[Usaco2008 Mar]牛跑步_A* Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. B ...

  3. BZOJ_4176_Lucas的数论_杜教筛+莫比乌斯反演

    BZOJ_4176_Lucas的数论_杜教筛+莫比乌斯反演 Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目“求 ...

  4. zookeeper(zkCli)命令概览

    连接: ./zkCli.sh -timeout 0 -r -server ip:port -timeout:当前会话的超时时间,zookeper依靠与客户端的心跳来判断会话是否有效,单位是毫秒-r: ...

  5. Esp8266

    原文:http://www.geek-workshop.com/thread-25582-1-1.html ----------------分割线----------------AT+RST OKet ...

  6. 基于 Maven 的多模块 Java ( Spring ) 项目构建

    索引: 开源Spring解决方案--lm.solution 参看代码 GitHub: solution/pom.xml pojo/pom.xml mapper/pom.xml common/pom.x ...

  7. Postman----打开postman console控制台,查看接口测试打印log

    经常在脚本中使用变量时,你可能需要看到变量获取到的值,你可以使用Postman Console去实现的.操作步骤:应用菜单-->View--->Show Postman Console,去 ...

  8. 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...

  9. 二分搜索树实现Java的Map(下)

    二分搜索树Map public class BSTMap<K extends Comparable<K>,V> implements Map<K,V> { priv ...

  10. Servlet底层原理、Servlet实现方式、Servlet生命周期

    Servlet简介 Servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. Servlet的特点 (1)Servlet对像,由Servlet容器 ...