[asp.net-mvc]注射 javascript 在 asp.net 中每一页上

发布时间: 2017/3/25 0:33:13
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我在网站上执行 GTM。网站有 400 + 的 GTM 脚本已放置的页。有任何的方式在 body 标签后注入 GTM 每页上的脚本吗?网站使用混合的技术,某些页面是在 ASP.NET 4.0 和一些 MVC 4.0。下面是要添加的示例脚本︰

<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-#####"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-#####');</script>
<!-- End Google Tag Manager -->

解决方法 1:

基于的编辑你做你的问题中,你需要一个 HTTP 模块,它将修改的代码,生成注入您的脚本。

首先你需要创建一个派生自流,那将会把你从 Response.Filter 的原始流的类。

public class GtmStream : Stream
{
    private static string gtmScript = @"<!-- Google Tag Manager -->...";

    private Stream _base;

    public GtmStream(Stream stream)
    {
        _base = stream;
    }

    public override void Flush()
    {
        _base.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _base.Read(buffer, offset, count);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var editedBuffer = GetByteArrayWithGtmScriptInjected(buffer);
        _base.Write(editedBuffer, offset, editedBuffer.Length);
    }

    public byte[] GetByteArrayWithGtmScriptInjected(byte[] buffer)
    {
        var stringValue = System.Text.Encoding.UTF8.GetString(buffer);
        if (!string.IsNullOrWhiteSpace(stringValue))
        {
            var position = stringValue.IndexOf("</body>");
            if (position != -1)
            {
                stringValue = stringValue.Insert(position + 7, gtmScript);    
            }
        }
        return System.Text.Encoding.UTF8.GetBytes(stringValue.ToCharArray());
    }

    public override bool CanRead
    {
        get { throw new NotImplementedException(); }
    }

    public override bool CanSeek
    {
        get { throw new NotImplementedException(); }
    }

    public override bool CanWrite
    {
        get { throw new NotImplementedException(); }
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotImplementedException();
    }

    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }

    public override long Length
    {
        get { throw new NotImplementedException(); }
    }

    public override long Position
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
}

每次写入将调用该方法,该流将检查是否它包含标记,并且如果它存在,将在它以后注入脚本代码。

然后它将返回新的字节数组,并在基础流上调用 Write 方法。

要把它插到你的 web 应用程序,您需要创建一个 HTTP 模块,如下︰

public class GtmScriptModule : IHttpModule
{
    private GtmStream gtmStream;

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        gtmStream = new GtmStream(application.Context.Response.Filter);
        application.Context.Response.Filter = gtmStream;
    }

    public void Dispose()
    {
    }
}

这只是将将 Response.Filter 设置为您自定义的流。

最后,您需要插入您 web 应用程序中的 HTTP 模块︰

<system.web>
    ...
    <httpModules>
      <add name="GtmScriptModule" type="TestMvcApplication.Modules.GtmScriptModule, TestMvcApplication" />
    </httpModules>
  </system.web>


如果你想要挖深在理论在这里是一些有用的链接︰

赞助商