从不同的域加载CSS,并从Javascript访问它
Loading CSS from different domain, and accessing it from Javascript
我想将我的网站拆分到不同的服务器上,并为此使用子域。
xttp://site.com将提供主php文件xttp://static.site.com将提供css和jsxttp://content.site.com将提供图像和此类
(xttp防止stackoverflow表单认为它是一个url(
有关原因,请阅读以下内容
然而,当我试图通过javascript访问任何css规则时,我遇到了一个问题。NS_ERROR_DOM_SECURITY_ERR。这是一种相对较新的安全措施,与防止跨域脚本有关。
过去,有一些措施可以解决这个问题,包括关闭这种保护。现在已经不起作用了。
我的问题:
如果一个正常加载的css规则来自不同的域,那么是否可以通过javascript访问它?
javascript:
MUI.getCSSRule=function(selector){
for(var ii=0;ii<document.styleSheets.length;ii++){
var mysheet=document.styleSheets[ii];
var myrules=mysheet.cssRules?mysheet.cssRules:mysheet.rules;
for(i=0;i<myrules.length;i++){
if(myrules[i].selectorText==selector){
return myrules[i]
}
}
}
return false
};
javascript和css是从具有绝对路径的html加载的
网站url为"http://site.com">
这两个域都完全在我的控制之下,但它们是独立的机器(目前是虚拟的,但如果可能的话,在生产中它们甚至可能不在同一个位置(
重新表述问题:
有没有办法让Firefox和其他浏览器知道,即使域名不同,它也应该将某些域视为相同的
为什么?因此,我可以轻松地使用不同的服务器,并根据其任务进行优化。php的快速机器,提供静态内容的简单机器,内容的大型机器。
为什么?成本。静态服务器通常不需要对任何下载文件的人进行安全保护。它的内容很少,因此不需要昂贵的阵列。只要把它载入记忆,然后从那里发球。内存本身也可能受到限制,试试看。不过,至少在我的情况下,PHP服务器通常需要大量内存,需要冗余存储和大量日志记录。内容服务器将需要大量的存储和大量的带宽,但在CPU能力方面相对较少。每个都有不同的硬件/主机要求。对每一个进行微调不仅可以提供更好的性能,还可以降低托管成本,至少对我来说,这仍然是运营网站的最大成本之一。
CORS(跨来源资源共享(是一种允许站点选择跨来源访问资源的标准。我不知道Firefox是否将此应用于CSS;我知道它适用于XMLHttpRequest,而且它将适用于大多数其他跨域请求限制,但我还没有在您的确切用例中测试过它。
您可以将以下标题添加到static.site.com
的响应中,以允许您的主页访问从那里提供的资源的内容:
Access-Control-Allow-Origin: http://site.com
甚至,如果你不认为static.site.com
上的任何内容是敏感的:
Access-Control-Allow-Origin: *
Mozilla开发者网络提供了更多信息。
我写了一个小函数,可以解决包括FF在内的跨浏览器加载问题。GitHub上的评论有助于解释用法。完整代码位于https://github.com/srolfe26/getXDomainCSS.
免责声明:下面的代码依赖于jQuery。
有时,如果你从一个无法控制CORS设置的地方提取CSS,你仍然可以用<link>
标签获得CSS,那么需要解决的主要问题就是知道你对CSS的调用何时已经加载并准备好使用。在较旧的IE中,可以在加载CSS时运行on_load
侦听器。
较新的浏览器似乎需要老式的轮询来确定何时加载文件,并且在确定何时满足加载时存在一些跨浏览器问题。请参阅下面的代码,了解其中的一些怪癖。
/**
* Retrieves CSS files from a cross-domain source via javascript. Provides a jQuery implemented
* promise object that can be used for callbacks for when the CSS is actually completely loaded.
* The 'onload' function works for IE, while the 'style/cssRules' version works everywhere else
* and accounts for differences per-browser.
*
* @param {String} url The url/uri for the CSS file to request
*
* @returns {Object} A jQuery Deferred object that can be used for
*/
function getXDomainCSS(url) {
var link,
style,
interval,
timeout = 60000, // 1 minute seems like a good timeout
counter = 0, // Used to compare try time against timeout
step = 30, // Amount of wait time on each load check
docStyles = document.styleSheets // local reference
ssCount = docStyles.length, // Initial stylesheet count
promise = $.Deferred();
// IE 8 & 9 it is best to use 'onload'. style[0].sheet.cssRules has problems.
if (navigator.appVersion.indexOf("MSIE") != -1) {
link = document.createElement('link');
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
link.onload = function () {
promise.resolve();
}
document.getElementsByTagName('head')[0].appendChild(link);
}
// Support for FF, Chrome, Safari, and Opera
else {
style = $('<style>')
.text('@import "' + url + '"')
.attr({
// Adding this attribute allows the file to still be identified as an external
// resource in developer tools.
'data-uri': url
})
.appendTo('body');
// This setInterval will detect when style rules for our stylesheet have loaded.
interval = setInterval(function() {
try {
// This will fail in Firefox (and kick us to the catch statement) if there are no
// style rules.
style[0].sheet.cssRules;
// The above statement will succeed in Chrome even if the file isn't loaded yet
// but Chrome won't increment the styleSheet length until the file is loaded.
if(ssCount === docStyles.length) {
throw(url + ' not loaded yet');
}
else {
var loaded = false,
href,
n;
// If there are multiple files being loaded at once, we need to make sure that
// the new file is this file
for (n = docStyles.length - 1; n >= 0; n--) {
href = docStyles[n].cssRules[0].href;
if (typeof href != 'undefined' && href === url) {
// If there is an HTTP error there is no way to consistently
// know it and handle it. The file is considered 'loaded', but
// the console should will the HTTP error.
loaded = true;
break;
}
}
if (loaded === false) {
throw(url + ' not loaded yet');
}
}
// If an error wasn't thrown by this point in execution, the stylesheet is loaded, proceed.
promise.resolve();
clearInterval(interval);
} catch (e) {
counter += step;
if (counter > timeout) {
// Time out so that the interval doesn't run indefinitely.
clearInterval(interval);
promise.reject();
}
}
}, step);
}
return promise;
}
document.domain = "site.com";
添加到CSS文件之前加载的JS文件中。我还将添加上面建议的HTTP头。
- 从数据库中获取数据并插入JavaScript变量
- 将值从Javascript传递并返回到VBScript,ASP中的Vice Versa
- 从数组中删除重复条目,并在javascript中按顺序排列
- 如何从文本区域获取数据并使用javascript进行解密
- 从javascript调用C#Web服务并使用它(json格式)
- 从javascript中调用的Android函数中获取值,并将其返回给js
- 从Div创建图像,并使用Javascript和ASP.net将其保存到服务器
- 使用javascript提交表单并从字段/单选框/复选框/文本区域获取数据
- 如何从django表单库中隐藏复选框,并使用Javascript切换其显示属性
- 从javascript调用codeigniter方法并传递数据
- 生成远程XML,并使用javascript从网页消费
- 使用 JavaScript 更改边框颜色,并从 Javascript 保存 Cookie
- 在Mysql表中查找并从javascript传递信息
- 我如何调用javascript函数并从javascript函数获得返回值
- 调整图片大小并从javascript上传到php
- 使用PHP变量作为ID并从Javascript调用
- Django url重写并从Javascript传递参数
- 展开和折叠一个项目,并从javascript中删除静态文本
- asp.net mvc-发布JSON和文件数据,并从JavaScript到mvc Web API控制器
- 从不同的域加载CSS,并从Javascript访问它