#这是可能的!阅读下文。
首先,让我用这张图来解释一下异步文件上传是如何实现的:
抱歉。我已经关闭了我的一个域,图像现在消失了。这是一个非常好的形象。这是在我发现 Stack Overflow 可以通过 Imgur 上传图片之前。
如您所见,诀窍是让 HTTP 响应加载到隐藏的 IFRAME 元素而不是页面本身。 (这是通过在使用 JavaScript 提交 FORM 时设置 FORM 元素的 target 属性来完成的。)
这行得通。但是,我面临的问题是服务器端脚本位于不同的域。 FORM-submit 是一个跨域的 HTTP 请求。现在,服务器端脚本启用了 CORS,这使我的网页有权读取从我的页面到该脚本的 HTTP 请求的响应数据——但这只有在我通过 AJAX 接收到 HTTP 响应时才有效,因此,JavaScript。
但是,在本例中,响应指向 IFRAME 元素。一旦 XML 响应进入 IFRAME,它的 URL 将是删除脚本——例如http://remote-domain.example/script.pl。
不幸的是,CORS 不涵盖这种情况(至少我认为)- 我无法读取 IFRAME 的内容,因为它的 URL 与页面的 URL(不同域)不匹配。我收到此错误:
Unsafe JavaScript attempt to access frame with URL hxxp://remote-domain.example/script.pl from frame with URL hxxp://example.com/outer.html. Domains, protocols and ports must match.
并且由于 IFRAME 的内容是一个 XML 文档,因此 IFRAME 中没有可以使用 postMessage 或其他东西的 JavaScript 代码。
所以我的问题是:如何从 IFRAME 中获取 XML 内容?
正如我上面所说,我能够直接检索跨域 HTTP 响应(启用 CORS),但是一旦它们加载到 IFRAME 中,我似乎无法读取跨域 HTTP 响应。
好像这个问题还不够无解,让我排除这些解决方案:
easyXDM 和类似技术需要远程域上的端点,
更改 XML 响应(以包含 SCRIPT 元素),
服务器端代理 - 我知道我的域上可以有一个服务器端脚本,它可以用作代理。
那么,除了这两种解决方案,还能做到这一点吗?
#可以做到!!
事实证明,可以伪造一个模仿 multipart/form-data FORM 提交的 XHR 请求(Ajax 请求)(在上图中用于上传文件到服务器)。
诀窍是使用 FormData 构造函数 - 阅读 this Mozilla Hacks article获取更多信息。
这是你的做法:
// STEP 1
// retrieve a reference to the file
// <input type="file"> elements have a "files" property
var file = input.files[0];
// STEP 2
// create a FormData instance, and append the file to it
var fd = new FormData();
fd.append('file', file);
// STEP 3
// send the FormData instance with the XHR object
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://remote-domain.example/script.pl', true);
xhr.onreadystatechange = responseHandler;
xhr.send(fd);
上述方法执行的是异步文件上传,相当于上图中描述的常规文件上传,通过提交这个表单来实现:
<form action="http://remote-domain.example/script.pl"
enctype="multipart/form-data" method="post">
<input type="file" name="file">
</form>
#像个老板:)
最佳答案
只需发送一个带有表单数据的跨域 XHR 请求,而不是提交表单。 CORS 仅适用于前者。
如果您必须以其他方式进行,请使用 postMessage 与框架协商。
And since the contents of the IFRAME is an XML document, there is no JavaScript code inside the IFRAME which could make use of postMessage or something.
这怎么阻止你?在 XML 的任意位置的 HTML 或 SVG 命名空间 ( <script xmlns="http://www.w3.org/1999/xhtml" type="application/ecmascript" src="..."/> ) 下包含脚本元素。
关于javascript - 是否可以执行异步跨域文件上传?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6718664/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta