Ï »¿символов, добавляемых в начало каждого файла

Я загрузил класс HttpHandler, который объединяет файлы JS в один файл и продолжает добавлять символы  в начале каждого файла, который он объединяет.

Есть идеи о том, что вызывает это? Может ли быть так, что обработанные файлы записываются в кеш, и именно так кеш хранит / отображает их?

Любой вклад будет очень признателен.

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; }
    }
}

Эта проблема также может повлиять на PHP, поэтому я хотел бы отметить ее, исходя из названия этого вопроса. Когда BOM отображается в верхней части файла PHP, заголовки не отправляются должным образом, и поэтому состояние сеанса не сохраняется между страницами. Преследование и решение может быть ошеломляющим, если вы не видели этого раньше. Проблема в том, что файл PHP был сохранен как UTF-8 вместо ASCII. Рекомендуется сохранять все файлы HTML, CSS и PHP как ASCII. В моем случае мне пришлось использовать шестнадцатеричный редактор с командой iconv для обнаружения символов, их удаления и повторного сохранения в ASCII.

Volomike 14.05.2012 20:03

Боковой комментарий ... мне кажется, что наличие символов "gzip" и / или "deflate" - не лучший способ проверить. Клиенты, которым не нужен сжатый контент, могут указать, например, «gzip; q = 0, deflate; q = 0».

Eric Kramer 25.11.2014 00:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
2
12 009
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Символы ï »¿- это Маркеры спецификации UTF.

Думаю, это Метка порядка байтов (BOM) для файлов с кодировкой UTF-8. Эта отметка позволяет определить, в какой кодировке хранится файл.

Это UTF Метка порядка байтов (BOM).

Он будет в начале каждого файла, но ваш редактор проигнорирует их там. При объединении они оказываются посередине, так что вы их видите.

Проверьте, как кодируются ваши файлы js, и укажите ту же кодировку в коде, который выполняет чтение и конкатенацию. Эти два символа обычно указывают на юникод.

я уже сделал это и как-то даже указал, что UTF8Encoding опускает спецификацию, он все равно ее записывает ..

IEnumerator 21.01.2009 23:09

Эти символы представляют собой спецификацию UTF-8. Не похоже, что они исходят из сжатого потока. Скорее всего, они вставлены в поток ответов, поэтому я предлагаю очистить ответ перед тем, как работать с ним:

context.Response.Clear();

Ваше предложение не удалось исправить. Кроме того, нижеприведенный флаг true должен опускать отметку порядка байтов, а это не так. UTF8Encoding encoding = новый UTF8Encoding (true);

IEnumerator 21.01.2009 23:07
Ответ принят как подходящий

Хорошо, я отладил ваш код.

Метки спецификации появляются в исходном потоке при чтении файлов с диска:

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

Если вы правильно прочитаете файлы, вы сможете избавиться от отметок.

Спасибо. я смог продолжить отладку и смог удалить отметки.

IEnumerator 22.01.2009 03:33

Вы не опубликовали фактическое решение. Вот моя душа. В строке, где он считывает файл в память, я нашел какой-то странный способ удалить спецификацию:

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

А еще вам понадобится эта функция:

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

Nitech

Если у вас есть содержимое файла в виде строки, .Trim () довольно легко отсекает "BOM".

Возможно, вы не сможете этого сделать, или вы можете хочу пробел в конце файла, но это, безусловно, вариант.

Для пробелов .js не важно, так что это может сработать.

хотя он и отображается в Firebug, он не мешает, поэтому я просто оставил его в покое.

IEnumerator 19.02.2010 23:47

Другие вопросы по теме