有可能的! 参见下文。
首先,让我用这张图来解释文件如何上传异步可以实现:
抱歉。 我已经关闭了我的领域之一,现在的图像消失。 这是一个非常良好的形象,虽然。 这是以前我发现堆栈溢出通过Imgur允许上传图片。
正如你所看到的,关键是让HTTP响应加载到一个隐藏的IFRAME元素,而不是页面本身。 (这是通过设置在完成的target
提交用JavaScript表单时FORM元素的属性。)
这工作。 不过,我所面临的问题是服务器端脚本是在不同的领域 。 形式提交是跨域HTTP请求。 现在,服务器端脚本CORS启用这给我的网页的权限读取从我的网页到该脚本由HTTP的请求的响应数据 - 但如果我收到通过Ajax的HTTP响应的作品而已, ERGO,JavaScript的。
但是,int该情况下,响应指向IFRAME元素。 而一旦XML响应登陆到IFRAME,它的URL将删除脚本-如http://remote-domain.com/script.pl
。
不幸的是,CORS不包括这种情况下(至少我认为) - 我无法读取IFRAME的内容,因为它的URL不匹配的页面(不同领域)的URL。 我得到这个错误:
从框架//remote-domain.com/script.pl与网址hxxp:不安全的JavaScript尝试与网址hxxp访问框架//my-domain.com/outer.html。 域,协议和端口必须匹配。
而且,由于该IFRAME的内容是一个XML文档,有IFRAME可能利用内部没有任何JavaScript代码postMessage
什么的。
所以我的问题是: 我怎样才能从IFRAME XML内容?
正如我前面所说,我可以直接检索跨域的HTTP响应(启用CORS),但似乎我无法一旦装载到一个IFRAME看跨域HTTP的响应。
而且好像这个问题是远远不够的不可解,让我排除这些解决方案 :
easyXDM以及需要对远程域终点类似的技术,
改变XML响应(以包括SCRIPT元件),
服务器端代理 - 我明白,我可以在我的域中的服务器端脚本这可以作为一个代理。
因此,除了这两个解决方案,可以这样做?
可以办到!!
事实证明,有可能伪造XHR请求(Ajax的请求),其模仿multipart/form-data
FORM提交(其上方的图像中的用于上载的文件到服务器)。
诀窍是使用FormData
构造-读这Mozilla的黑客文章以获取更多信息。
这是你如何做到这一点:
// 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.com/script.pl', true);
xhr.onreadystatechange = responseHandler;
xhr.send(fd);
上述方法执行异步文件uplaod,这等同于由提交此表格上方的图像中的描述和实现的常规文件上传:
<form action="http://remote-domain.com/script.pl"
enctype="multipart/form-data" method="post">
<input type="file" name="file">
</form>