XMLHttpRequest原始空值不允许Access-Control-Allow-Origin用于file:///到file:///(无服务器)

我试图创build一个网站,可以通过启动其索引文件在本地下载和运行。

所有文件都是本地的,没有资源在线使用。

当我尝试使用jQuery的AJAXSLT插件来处理带有XSL模板的XML文件(在子目录中)时,我收到以下错误:

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/data/home.xml. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/assets/xsl/main.xsl. Origin null is not allowed by Access-Control-Allow-Origin.

发出请求的索引文件是file:///C:/path/to/XSL%20Website/index.html而使用的JavaScript文件存储在file:///C:/path/to/XSL%20Website/assets/js/

我该如何解决这个问题?

对于不能运行本地networking服务器的情况,您可以允许Chrome通过浏览器开关访问file://文件。 经过一番挖掘,我发现这个讨论 ,其中提到了一个浏览器开关后的开关。 运行你的Chrome实例:

 chrome.exe --allow-file-access-from-files 

这对于开发环境来说可能是可以接受的,但是其他的很less 你当然不会一直想要这个。 这似乎仍然是一个悬而未决的问题(截至2011年1月)。

另请参见: 在Chrome中使用本地文件的jQuery getJSON问题

从本质上来说,处理这个问题的唯一方法是在本地主机上运行一个web服务器,并从那里为它们提供服务。

浏览器允许ajax请求访问计算机上的任何文件是不安全的,因此大多数浏览器似乎将“file://”请求视为没有来源的“ 相同来源策略 ”

启动一个web服务器可以像进入文件所在的目录一样简单:

 python -m SimpleHTTPServer 

这里是一个applescript,它将启动Chrome,打开–allow-file-access-from-files开关,用于OSX / Chrome开发者:

 set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" set switch to " --allow-file-access-from-files" do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &" 

该解决scheme将允许您使用jQuery.getScript()加载本地脚本。 这是一个全局设置,但您也可以在每个请求的基础上设置crossDomain选项。

 $.ajaxPrefilter( "json script", function( options ) { options.crossDomain = true; }); 

那么使用JavaScript FileReader函数打开本地文件,即:

 <input type="file" name="filename" id="filename"> <script> $("#filename").change(function (e) { if (e.target.files != undefined) { var reader = new FileReader(); reader.onload = function (e) { // Get all the contents in the file var data = e.target.result; // other stuffss................ }; reader.readAsText(e.target.files.item(0)); } }); </script> 

现在单击Choose filebutton并浏览到文件file:///C:/path/to/XSL%20Website/data/home.xml

像这样启动Chrome来绕过这个限制: open -a "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --args --allow-file-access-from-files

来自Josh Lee的评论,但我需要指定谷歌浏览器的完整path,以避免谷歌浏览器从我的Windows分区(在Parallels中)打开。

您可以尝试在response.writeHead(, {[here]})放入'Access-Control-Allow-Origin':'*'

我刚刚解决这个问题的方法不是使用XMLHTTPRequest,而是在单独的JavaScript文件中包含所需的数据。 (在我的情况下,我需要一个二进制SQLite blob与https://github.com/kripken/sql.js/使用);

我创build了一个名为base64_data.js的文件(并使用btoa()来转换我需要的数据并将其插入<div>以便我可以复制它)。

 var base64_data = "U1FMaXRlIGZvcm1hdCAzAAQA ...<snip lots of data> AhEHwA=="; 

然后将数据包含在html中,就像普通的javascript:

 <div id="test"></div> <script src="base64_data.js"></script> <script> data = atob(base64_data); var sqldb = new SQL.Database(data); // Database test code from the sql.js project var test = sqldb.exec("SELECT * FROM Genre"); document.getElementById("test").textContent = JSON.stringify(test); </script> 

我想这将是微不足道的修改这个阅读JSON,甚至XML; 我将把它作为读者的练习;)

Interesting Posts