developer tip

가상 디렉터리가 있거나없는 CssRewriteUrlTransform

copycodes 2020. 12. 1. 08:20
반응형

가상 디렉터리가 있거나없는 CssRewriteUrlTransform


우리는 사이트에서 MVC 번들링을 사용 CssRewriteUrlTransform하고 있으며 이미지 URL이 동적 번들 CSS 파일에서 작동하는지 확인합니다.

그러나 이것은 가상 디렉토리를 사용하지 않을 때만 작동합니다.

http://localhost/VirttualDir작동하지 않지만 작동 http://localhost/합니다. 이는 변환이 CssRewriteUrlTransformURL을 다시 작성할 때 가상 폴더를 고려하지 않기 때문 입니다. 따라서 이미지 실제 경로 가 잘못된 localhost/vdir/content/img/foo.png경우 다시 작성합니다.localhost/content/img/foo.png


나는 당신의 문제를 완전히 이해하지 못하지만 http://localhost여기서 보는 것은 잘못된 것 같습니다. 번들에 절대 URL을 사용해서는 안됩니다.

나를 위해 CssRewriteUrlTransform은 완벽하게 작동하며 사용 방법은 다음과 같습니다.

bundles.Add(new StyleBundle("~/bundles/css").Include(
                "~/Content/css/*.css", new CssRewriteUrlTransform()));

"번들"은 가상입니다.

도움이 되나요?

최신 정보

IIS VirtualDir에 대해 이야기 할 때 "VirtualDir"와 헷갈 렸고 Bundle VirtualDir를 생각했습니다! 이 경우 CssRewriteUrlTransform이 URL을 Host / VirtualDir URI가 아닌 호스트에 다시 쓰는 것은 사실입니다.

그렇게하려면 CssRewriteUrlTransform을 파생하여 필요한 작업을 수행해야합니다. 여기에 좋은 토론이 있습니다 : Twitter Bootstrap을 사용한 ASP.NET MVC4 번들링

가장 좋은 대답은 http://aspnetoptimization.codeplex.com/workitem/83입니다.

public class CssRewriteUrlTransformWrapper : IItemTransform
{
    public string Process(string includedVirtualPath, string input)
    {           
        return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);           
    }
}

CssRewriteUrlTransform 대신이 클래스 사용


나는 같은 문제가 있었다. 이것이 내가 수정 한 방법입니다.

private class ProperUrlRewrite : IItemTransform
{
    private static string RebaseUrlToAbsolute(string baseUrl, string url)
    {
        if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase) || url.Contains(':'))
            return url;
        return VirtualPathUtility.Combine(baseUrl, url);
    }
    private static Regex UrlPattern = new Regex("url\\s*\\(['\"]?(?<url>[^)]+?)['\"]?\\)");
    public string Process(string includedVirtualPath, string input)
    {
        if (includedVirtualPath == null)
            throw new ArgumentNullException("includedVirtualPath");
        if (string.IsNullOrWhiteSpace(input))
            return input;

        string directory = VirtualPathUtility.GetDirectory(VirtualPathUtility.ToAbsolute(includedVirtualPath));
        if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
            directory += "/";
        return UrlPattern.Replace(input, match => "url(" + ProperUrlRewrite.RebaseUrlToAbsolute(directory, match.Groups["url"].Value) + ")");
    }
}

나는 그것이 완벽하지 않다는 것을 알고 있으며 이것이 잘못 될 수있는 많은 경우가 있다는 것을 알고 있습니다 (처음에 정규식을 사용하여 CSS 파일을 구문 분석 할 수 있는지 확실하지 않습니다-이것이 정확히 원본 CssRewriteUrlTransform이하는 것입니다). 멀리서 ...


'CssRewriteUrlTransform'은 가상 디렉터리 위에서 실행되지 않는 응용 프로그램에 대해 잘 작동합니다.

따라서 앱이 http://your-site.com/에서 실행되는 경우 정상적으로 실행되지만 http://your-site.com/your-app/에서 실행되는 경우 모든 이미지에 대해 404가 표시됩니다. 기본 'CssFixRewriteUrlTransform'이 '/'로 이미지를 참조하기 때문입니다.

이것을 사용하십시오 :

public class CssFixRewriteUrlTransform: IItemTransform {

    private static string ConvertUrlsToAbsolute(string baseUrl, string content) {
        if (string.IsNullOrWhiteSpace(content)) {
            return content;
        }
        var regex = new Regex("url\\(['\"]?(?<url>[^)]+?)['\"]?\\)");
        return regex.Replace(content, match = > string.Concat("url(", RebaseUrlToAbsolute(baseUrl, match.Groups["url"].Value), ")"));
    }

    public string Process(string includedVirtualPath, string input) {
        if (includedVirtualPath == null) {
            throw new ArgumentNullException("includedVirtualPath");
        }
        var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
        return ConvertUrlsToAbsolute(directory, input);
    }

    private static string RebaseUrlToAbsolute(string baseUrl, string url) {
        if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase)) {
            return url;
        }
        if (!baseUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase)) {
            baseUrl = string.Concat(baseUrl, "/");
        }
        return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
    }
}

참고 : .min.css로 모든 파일 css를 삭제하십시오. 그렇지 않으면 수정되지 않기 때문입니다.


I have problems with url that contains "data" and even a url inner another one, so I have to re-do the regex, this is my solution:

public string Process(string includedVirtualPath, string input)
    {
        if (includedVirtualPath == null)
        {
            throw new ArgumentNullException(nameof(includedVirtualPath));
        }

        if (string.IsNullOrWhiteSpace(input))
        {
            return input;
        }

        var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
        if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
        {
            directory += "/";
        }

        return new Regex(@"url\s*\(\s*([\'""]?)(?<scheme>(?:(?:data:)|(?:https?:))?)(?<url>(\\\1|.)*?)\1\s*\)")
            .Replace(input, match => string.Concat(
                "url(",
                match.Groups[1].Value,
                match.Groups["scheme"].Value,
                match.Groups["scheme"].Value == "" ?
                    RebaseUrlToAbsolute(directory, match.Groups["url"].Value) :
                    match.Groups["url"].Value,
                match.Groups[1].Value,
                ")"
            ));
    }

    private static string RebaseUrlToAbsolute(string baseUrl, string url)
    {
        if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl)
            || url.StartsWith("/", StringComparison.OrdinalIgnoreCase))
        {
            return url;
        }

        return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
    }
}

based on RegEx: Grabbing values between quotation marks

참고URL : https://stackoverflow.com/questions/19765238/cssrewriteurltransform-with-or-without-virtual-directory

반응형