1

我有一个 ASP.Net MVC 4 项目。如果我想让 TinyMCE 使用 gzip,我需要在我的页面中使用以下内容(例如):

<script type="text/javascript" src="/Scripts/tiny_mce/tiny_mce_gzip.js"></script>
<script type="text/javascript">
    tinyMCE_GZ.init({
        plugins: 'style,layer,table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras',
        themes: 'simple,advanced',
        languages: 'en',
        disk_cache: true,
        debug: false
    });
</script>

我注意到这在使用开发 Web 服务器进行测试时效果很好,但在部署到 IIS7 时却不行。进一步调查显示针对以下请求的 404(未找到文件):

/Scripts/tiny_mce/tiny_mce_gzip.ashx?js=true&diskcache=true&core=true&suffix=&themes=simple%2Cadvanced&plugins=style%2Clayer...

ashx 文件确实存在于相应的文件夹中,但 IIS 出于某种原因不会提供它。我尝试添加以下路由处理程序,但都没有任何区别:

routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
routes.IgnoreRoute("{*allashx}", new { allashx = @".*\.ashx(/.*)?" }); 
4

1 回答 1

0

解决了

上网一查,发现有很多相同的问题,似乎没有人找到解决办法!(甚至在 TinyMCE 支持页面上)。所以我提出了一个解决方案,我希望它不会被诅咒:)

您唯一需要配置的是 Global.asax 中的“TinyMceScriptFolder”变量 - 它必须指向您的 TinyMCE 脚本文件夹(duh)(确保您不要以该路径开头,/否则路由处理程序将拒绝它。它将工作在任何情况下都从您网站的根目录开始)

TinyMCEGzipHandler.cs(从原始的 .ashx 文件复制,但添加了一些内容)

using System;
using System.Web;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Property;

namespace Softwarehouse.TinyMCE
{
    public class GzipHandler : IHttpHandler
    {
        private HttpResponse Response;
        private HttpRequest Request;
        private HttpServerUtility Server;

        public void ProcessRequest(HttpContext context)
        {
            this.Response = context.Response;
            this.Request = context.Request;
            this.Server = context.Server;
            this.StreamGzipContents();
        }

        public bool IsReusable
        {
            get { return false; }
        }

        #region private

        private void StreamGzipContents()
        {
            string cacheKey = "", cacheFile = "", content = "", enc, suffix, cachePath;
            string[] plugins, languages, themes;
            bool diskCache, supportsGzip, isJS, compress, core;
            int i, x, expiresOffset;
            GZipStream gzipStream;
            Encoding encoding = Encoding.GetEncoding("windows-1252");
            byte[] buff;

            // Get input
            plugins = GetParam("plugins", "").Split(',');
            languages = GetParam("languages", "").Split(',');
            themes = GetParam("themes", "").Split(',');
            diskCache = GetParam("diskcache", "") == "true";
            isJS = GetParam("js", "") == "true";
            compress = GetParam("compress", "true") == "true";
            core = GetParam("core", "true") == "true";
            suffix = GetParam("suffix", "") == "_src" ? "_src" : "";
            cachePath = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder); // Cache path, this is where the .gz files will be stored
            expiresOffset = 10; // Cache for 10 days in browser cache

            // Custom extra javascripts to pack
            string[] custom =
                {
/*
            "some custom .js file",
            "some custom .js file"
        */
                };

            // Set response headers
            Response.ContentType = "text/javascript";
            Response.Charset = "UTF-8";
            Response.Buffer = false;

            // Setup cache
            Response.Cache.SetExpires(DateTime.Now.AddDays(expiresOffset));
            Response.Cache.SetCacheability(HttpCacheability.Public);
            Response.Cache.SetValidUntilExpires(false);

            // Vary by all parameters and some headers
            Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
            Response.Cache.VaryByParams["theme"] = true;
            Response.Cache.VaryByParams["language"] = true;
            Response.Cache.VaryByParams["plugins"] = true;
            Response.Cache.VaryByParams["lang"] = true;
            Response.Cache.VaryByParams["index"] = true;

            // Is called directly then auto init with default settings
            if (!isJS)
            {
                Response.WriteFile(Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/tiny_mce_gzip.js"));
                Response.Write("tinyMCE_GZ.init({});");
                return;
            }

            // Setup cache info
            if (diskCache)
            {
                cacheKey = GetParam("plugins", "") + GetParam("languages", "") + GetParam("themes", "");

                for (i = 0; i < custom.Length; i++)
                    cacheKey += custom[i];

                cacheKey = MD5(cacheKey);

                if (compress)
                    cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".gz";
                else
                    cacheFile = cachePath + "/tiny_mce_" + cacheKey + ".js";
            }

            // Check if it supports gzip
            enc = Regex.Replace("" + Request.Headers["Accept-Encoding"], @"\s+", "").ToLower();
            supportsGzip = enc.IndexOf("gzip") != -1 || Request.Headers["---------------"] != null;
            enc = enc.IndexOf("x-gzip") != -1 ? "x-gzip" : "gzip";

            // Use cached file disk cache
            if (diskCache && supportsGzip && File.Exists(cacheFile))
            {
                Response.AppendHeader("Content-Encoding", enc);
                Response.WriteFile(cacheFile);
                return;
            }

            // Add core
            if (core)
            {
                content += GetFileContents("tiny_mce" + suffix + ".js");

                // Patch loading functions
                content += "tinyMCE_GZ.start();";
            }

            // Add core languages
            for (x = 0; x < languages.Length; x++)
                content += GetFileContents("langs/" + languages[x] + ".js");

            // Add themes
            for (i = 0; i < themes.Length; i++)
            {
                content += GetFileContents("themes/" + themes[i] + "/editor_template" + suffix + ".js");

                for (x = 0; x < languages.Length; x++)
                    content += GetFileContents("themes/" + themes[i] + "/langs/" + languages[x] + ".js");
            }

            // Add plugins
            for (i = 0; i < plugins.Length; i++)
            {
                content += GetFileContents("plugins/" + plugins[i] + "/editor_plugin" + suffix + ".js");

                for (x = 0; x < languages.Length; x++)
                    content += GetFileContents("plugins/" + plugins[i] + "/langs/" + languages[x] + ".js");
            }

            // Add custom files
            for (i = 0; i < custom.Length; i++)
                content += GetFileContents(custom[i]);

            // Restore loading functions
            if (core)
                content += "tinyMCE_GZ.end();";

            // Generate GZIP'd content
            if (supportsGzip)
            {
                if (compress)
                    Response.AppendHeader("Content-Encoding", enc);

                if (diskCache && cacheKey != "")
                {
                    // Gzip compress
                    if (compress)
                    {
                        using (Stream fileStream = File.Create(cacheFile))
                        {
                            gzipStream = new GZipStream(fileStream, CompressionMode.Compress, true);
                            buff = encoding.GetBytes(content.ToCharArray());
                            gzipStream.Write(buff, 0, buff.Length);
                            gzipStream.Close();
                        }
                    }
                    else
                    {
                        using (StreamWriter sw = File.CreateText(cacheFile))
                        {
                            sw.Write(content);
                        }
                    }

                    // Write to stream
                    Response.WriteFile(cacheFile);
                }
                else
                {
                    gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress, true);
                    buff = encoding.GetBytes(content.ToCharArray());
                    gzipStream.Write(buff, 0, buff.Length);
                    gzipStream.Close();
                }
            }
            else
                Response.Write(content);
        }

        private string GetParam(string name, string def)
        {
            string value = Request.QueryString[name] != null ? "" + Request.QueryString[name] : def;

            return Regex.Replace(value, @"[^0-9a-zA-Z\\-_,]+", "");
        }

        private string GetFileContents(string path)
        {
            try
            {
                string content;

                path = Server.MapPath("/" + MvcApplication.TinyMceScriptFolder + "/" + path);

                if (!File.Exists(path))
                    return "";

                StreamReader sr = new StreamReader(path);
                content = sr.ReadToEnd();
                sr.Close();

                return content;
            }
            catch (Exception ex)
            {
                // Ignore any errors
            }

            return "";
        }

        private string MD5(string str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(str));
            str = BitConverter.ToString(result);

            return str.Replace("-", "");
        }

        #endregion
    }
}

全球.asax

public const string TinyMceScriptFolder = "Scripts/htmleditor";

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute(TinyMceScriptFolder + "/tiny_mce_gzip.ashx");
}

网页配置

<system.webServer>
  <httpHandlers>
    <add name="TinyMCEGzip" verb="GET" path="tiny_mce_gzip.ashx" type="Softwarehouse.TinyMCE.GzipHandler"/>
  </httpHandlers>
</system.webServer>
于 2013-07-12T09:56:14.050 回答