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

发布时间:2018-12-30 15:02  浏览次数:80



 

像素跟踪虽然是最早用于跟踪营销转换的方法,但它仍然被广泛使用,像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; } } }
存储数据与此逻辑无关,您可以使用任何存储来保存收集的数据。

标签

归档

阅读排行

支付宝搜索“559315787”,天天领红包