Jake Hall
Jake Hall

Reputation: 2102

How do I force ScriptManager to serve CDN scripts over SSL

We have a site served on a web farm. The farm is behind an SSL Accellerator which handles the encryption. This means that our IIS servers see all incoming connections as http, even though users all connect to the site via https.

We are beginning to use the EnableCDN=true property of ScriptManager. While on our dev environments where there is no SSL Accellerator the references to the js files on the CDN are rendered with https, on the production environment they are rendered insecurely over http which is causing the js to be blocked with "Only secure content is displayed" errors.

Short of manually updating all the script references in scriptmanager or re-writing the HTML on the way out via a module, does anyone know of a way to force the scriptmanager to render its references via https?

EDIT:

After doing some reflector review, I don't believe this is possible. I've put the following hack into place, however this is obviously fragile as it involves accessing a private field. If anyone can see a better way I would love to hear it.

var secureConnectionField = ScriptManager.GetType().GetField("_isSecureConnection", BindingFlags.Instance | BindingFlags.NonPublic);
if (secureConnectionField != null)
    secureConnectionField.SetValue(ScriptManager, true);

Upvotes: 12

Views: 2905

Answers (5)

percebus
percebus

Reputation: 847

Wether you are using @Razor it ASPX, I assume you have a Layout/MasterPage somewhere.

CDNs' true power lies in specifically having the script remotely hosted from some other source than your server's. Doing so prompts to be more likely that the user's browser has picked it up from a different location. CDNs perform best for core libraries, such as AngularJS or jQuery. The less popular the script you are importing is, the less recommended is to serve it through CDN.

I find it more suitable to hardcode-it on your Layout. If you use just the // instead specifying the protocol with http:// or https:// it should pick up the same protocol the page is being called.

<script type="text/javascript" src="//{yourCDNsource}"></script>

If you locally compress/minify a remote CDN it defeats the purpose. Better use NuGet or Bower for those.

Check Google CDNs

Upvotes: 0

Marco Bettiolo
Marco Bettiolo

Reputation: 5171

To handle a situation similar to yours, I configured the BundleCollection to use the CDN and two different version of the library for debug and production.

The result of these settings is that the non minified one will be used while debugging and the minified one from CDN will be used in production. The local minified one is ignored.

[...]  
bundles.UseCdn = true;
[...]
var jQueryBundle = new ScriptBundle("~/bundles/jquery");
jQueryBundle.CdnPath = "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
jQueryBundle.Include("~/scripts/jquery-1.9.1.js");
jQueryBundle.Include("~/scripts/jquery-1.9.1.min.js");
bundles.Add(jQueryBundle);

Note that I have not specified the protocol in the CdnPath, the client's browser will automatically use the current protocol the client is connected from, http or https.

The client's browser will receive the following tag in production:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

The developer's browser will receive the following tag:

<script src="/Scripts/jquery-1.9.1.js"></script>

Both will use the correct protocol on the browser.

Upvotes: 1

Swapnil Tandel
Swapnil Tandel

Reputation: 94

Use this global.asax

void Application_Start(object sender, EventArgs e) {

// map a simple name to a path

ScriptManager.ScriptResourceMapping.AddDefinition("jQuery", new ScriptResourceDefinition {

    Path = "~/scripts/jquery-1.3.2.min.js",

    DebugPath = "~/scripts/jquery-1.3.2.js",

    CdnPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js",

    CdnDebugPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.js"

});

}

Upvotes: -1

Maxim Kornilov
Maxim Kornilov

Reputation: 6065

If you use ASP.NET 4.0 or higher then one of the solution is to use ScriptResourceMapping feature of the ScriptManager control.

For example in global asax you can add the following code:

void Application_Start(object sender, EventArgs e) {

// map a simple name to a path

ScriptManager.ScriptResourceMapping.AddDefinition("jQuery", new ScriptResourceDefinition {

    Path = "~/scripts/jquery-1.3.2.min.js",

    DebugPath = "~/scripts/jquery-1.3.2.js",

    CdnPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js",

    CdnDebugPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.js"

});

}

So, as you can see you can set CDN paths explicitly. Also, you can override the script mapping for standard Ajax files.

More information can be found in this article: http://weblogs.asp.net/infinitiesloop/archive/2009/11/23/asp-net-4-0-scriptmanager-improvements.aspx

Upvotes: 1

user1088520
user1088520

Reputation:

Normally your development and production servers will have different IP ranges. Ask the developement team to apply a "protocol switch" based on the IP addresses in the framework dlls.

Upvotes: 0

Related Questions