Frage

Ich habe eine Httphandler Klasse heruntergeladen, die JS-Dateien in eine Datei verknüpft, und es hält zu Beginn jeder Datei, die  Zeichen anhängt es verkettet.

Alle Ideen, was ist der Grund dafür? Könnte es sein, dass die Dateien onces verarbeitet sie in den Cache geschrieben werden, und das ist, wie der Cache speichert / sie machen?

würden Alle Eingänge sehr geschätzt.

using System;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Configuration;
using System.Web;

public class HttpCombiner : IHttpHandler {

    private const bool DO_GZIP = false;
    private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays(30);

    public void ProcessRequest (HttpContext context) {

        HttpRequest request = context.Request;

        // Read setName, contentType and version. All are required. They are
        // used as cache key
        string setName = request["s"] ?? string.Empty;
        string contentType = request["t"] ?? string.Empty;
        string version = request["v"] ?? string.Empty;

        // Decide if browser supports compressed response
        bool isCompressed = DO_GZIP && this.CanGZip(context.Request);

        // Response is written as UTF8 encoding. If you are using languages
        // like Arabic, you should change this to proper encoding 
        UTF8Encoding encoding = new UTF8Encoding(false);

        // If the set has already been cached, write the response directly
        // from cache. Otherwise generate the response and cache it
        if (!this.WriteFromCache(context, setName, version, isCompressed,
            contentType))
        {
            using (MemoryStream memoryStream = new MemoryStream(5000))
            {
                // Decide regular stream or GZipStream based on whether the
                // response can be cached or not
                using (Stream writer = isCompressed
                    ? (Stream)(new GZipStream(memoryStream,
                        CompressionMode.Compress))
                    : memoryStream)
                {
                    // Load the files defined in <appSettings> and process
                    // each file
                    string setDefinition = System.Configuration
                        .ConfigurationManager.AppSettings[setName] ?? "";
                    string[] fileNames = setDefinition.Split(
                        new char[] { ',' }, 
                        StringSplitOptions.RemoveEmptyEntries);

                    foreach (string fileName in fileNames)
                    {
                        byte[] fileBytes = this.GetFileBytes(
                            context, fileName.Trim(), encoding);
                        writer.Write(fileBytes, 0, fileBytes.Length);
                    }

                    writer.Close();
                }

                // Cache the combined response so that it can be directly
                // written in subsequent calls 
                byte[] responseBytes = memoryStream.ToArray();
                context.Cache.Insert(
                    GetCacheKey(setName, version, isCompressed),
                    responseBytes, null,
                    System.Web.Caching.Cache.NoAbsoluteExpiration,
                    CACHE_DURATION);

                // Generate the response
                this.WriteBytes(responseBytes, context, isCompressed,
                    contentType);
            }
        }
    }

    private byte[] GetFileBytes(HttpContext context, string virtualPath,
        Encoding encoding)
    {
        if (virtualPath.StartsWith("http://",
            StringComparison.InvariantCultureIgnoreCase))
        {
            using (WebClient client = new WebClient())
            {
                return client.DownloadData(virtualPath);
            }
        }
        else
        {
            string physicalPath = context.Server.MapPath(virtualPath);
            byte[] bytes = File.ReadAllBytes(physicalPath);
            // TODO: Convert unicode files to specified encoding.
            // For now, assuming files are either ASCII or UTF8
            return bytes;
        }
    }

    private bool WriteFromCache(HttpContext context, string setName,
        string version, bool isCompressed, string contentType)
    {
        byte[] responseBytes = context.Cache[GetCacheKey(setName, version,
            isCompressed)] as byte[];

        if (null == responseBytes || 0 == responseBytes.Length) return false;

        this.WriteBytes(responseBytes, context, isCompressed, contentType);
        return true;
    }

    private void WriteBytes(byte[] bytes, HttpContext context, 
        bool isCompressed, string contentType)
    {
        HttpResponse response = context.Response;

        response.AppendHeader("Content-Length", bytes.Length.ToString());
        response.ContentType = contentType;
        if (isCompressed)
            response.AppendHeader("Content-Encoding", "gzip");

        context.Response.Cache.SetCacheability(HttpCacheability.Public);
        context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION));
        context.Response.Cache.SetMaxAge(CACHE_DURATION);
        context.Response.Cache.AppendCacheExtension(
            "must-revalidate, proxy-revalidate");

        response.OutputStream.Write(bytes, 0, bytes.Length);
        response.Flush();
    }

    private bool CanGZip(HttpRequest request)
    {
        string acceptEncoding = request.Headers["Accept-Encoding"];
        if (!string.IsNullOrEmpty(acceptEncoding) &&
             (acceptEncoding.Contains("gzip")
                 || acceptEncoding.Contains("deflate")))
            return true;
        return false;
    }

    private string GetCacheKey(string setName, string version,
        bool isCompressed)
    {
        return "HttpCombiner." + setName + "." + version + "." + isCompressed;
    }

    public bool IsReusable
    {
        get { return true; }
    }
}
War es hilfreich?

Lösung

OK, ich habe Ihren Code debuggen.

BOM Markierungen im Quellstrom erscheinen, wenn die Dateien von der Festplatte gelesen werden:

byte[] bytes = File.ReadAllBytes(physicalPath);
// TODO: Convert unicode files to specified encoding. For now, assuming
// files are either ASCII or UTF8

Wenn Sie die Dateien richtig zu lesen, können Sie loswerden der Markierungen erhalten.

Andere Tipps

Die ï »¿Zeichen sind die UTF BOM Marker .

Es ist die UTF Byte Order Mark (BOM) .

Es wird am Anfang jeder Datei, aber der Editor wird sie es ignorieren. Wenn verketteten landen sie in der Mitte, so dass Sie sehen, wie sie.

Ich denke, das ist die Byte Order Mark (BOM) für Dateien mit UTF-8 Codierung. Diese Markierung ermöglicht es in dem, was codiert, um die Datei zu bestimmen, wird gespeichert.

Wenn Sie den Inhalt der Datei in einem String haben, .Trim () wird die "BOM" ganz praktisch abhauen.

Sie können nicht in der Lage sein, das zu tun, oder Sie können wollen die Leerzeichen an dem Enden der Datei, aber es ist sicherlich eine Option.

Für Js Leerzeichen ist nicht signifikant, so könnte dies arbeiten.

Überprüfen Sie, wie Sie Ihre js Dateien verschlüsselt sind und die gleiche Codierung im Code bereitzustellen, die das Lesen und Verkettung der Fall ist. Diese beiden Zeichen weisen in der Regel auf Unicode.

Diese Zeichen sind UTF-8 BOM. Es scheint nicht, wie sie aus dem gzip-Stream kommen. Es ist eher wahrscheinlich, dass sie in den Antwortstream eingefügt werden, so würde ich vorschlagen, die Antwort, bevor die Arbeit mit dem Löschen:

context.Response.Clear();

Sie haben nicht nach, was die eigentliche Lösung war. Hier ist meine soulution. Auf der Linie, wo sie die Datei in dem Speicher lesen, fand ich eine Art seltsamer Weise die Stückliste zu entfernen:

byte[] bytes = File.ReadAllBytes(physicalPath);
String ss = new StreamReader(new MemoryStream(bytes), true).ReadToEnd();
byte[] b = StrToByteArray(ss);
return b;  

Und Sie müssen auch diese Funktion:

public static byte[] StrToByteArray(string str)
{
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);
} 

Nitech

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top