在使用FormData时如何添加XMLHttpRequest的头数据?

69

我正在尝试实现一个文件上传API,给出的链接如下:
Mediafire文件上传

我已经成功地上传了Post dataGet data,但不知道如何发送Header data中的x-filename属性,这在API指南中有说明。

我的代码:

xmlhttp=new XMLHttpRequest();
var formData = new FormData();

formData.append("Filedata", document.getElementById("myFile").files[0]);

var photoId = getCookie("user");
// formData.append("x-filename", photoId);            //tried this but doesn't work
// xmlhttp.setRequestHeader("x-filename", photoId);   //tried this too (gives error) [edited after diodeous' answer]

xmlhttp.onreadystatechange=function()
{
    alert("xhr status : "+xmlhttp.readyState);
}

var url = "http://www.mediafire.com/api/upload/upload.php?"+"session_token="+getCookie("mSession")+"&action_on_duplicate=keep";

xmlhttp.open("POST", url);
// xmlhttp.setRequestHeader("x-filename", photoId);   //tried this too, doesnt work. Infact nothing gets uploaded on mediafire.  [edited after apsillers' answer]
// cant get response due to same origin policy
xmlhttp.send(formData);

您能给我们提供“setRequestHeader”的错误文本吗? - apsillers
这是JavaScript代码,因此没有错误文本,脚本只会停止执行,可能是因为它不被允许。 - Rajdeep Siddhapura
只是想澄清一下,您的意思是您的浏览器JavaScript控制台中没有错误吗? - apsillers
@apsillers 哦,我从未听说过Javascript Console
错误: 未捕获的 InvalidStateError: 尝试使用一个不可用或不再可用的对象。 upload.php:42
uploadAjax upload.php:42
onclick upload.php:130
- Rajdeep Siddhapura
@apsillers 的第 42 行是 setRequestHeader 行,第 130 行有一个带有 onclick 属性的按钮,用于调用上述代码。 - Rajdeep Siddhapura
3个回答

124

您的错误

InvalidStateError:尝试使用不可用或不再可用的对象

出现的原因是您必须在调用open之后调用setRequestHeader。只需将setRequestHeader行移到open行下面(但在send之前):

xmlhttp.open("POST", url);
xmlhttp.setRequestHeader("x-filename", photoId);
xmlhttp.send(formData);

已经解决了错误,但仍然无法正常工作。实际上,由于同源策略,无法从Mediafire获取响应。不知道问题出在哪里,请您检查一下Mediafire API,并让我知道问题所在。在没有进行此编辑的情况下,文件已成功上传到Mediafire,现在却无法上传! - Rajdeep Siddhapura
没有那一行,文件会被上传,但是使用默认名称! - Rajdeep Siddhapura
4
有点清晰了。请参见理解跨源资源共享的XMLHttpRequest。同源策略允许“简单”请求到达客户端,然后决定客户端是否可以读取结果。“非简单”请求在发送实际请求之前将通过“预检”请求进行验证。添加非简单头使您的请求从简单变为非简单。在这两种情况下,我假设您无法阅读来自服务器的响应? - apsillers
或者我可以在将文件发送到Mediafire之前更改上传的文件名,这样我就不需要发送额外的参数了。 - Rajdeep Siddhapura
哦,很好知道添加头信息会使请求变得非简单。谢谢你的帮助 :) - Rajdeep Siddhapura

38
使用:xmlhttp.setRequestHeader(key, value);

1
我也尝试过这个,但是在这条语句之后JavaScript停止执行了,不起作用!(我会把这个加到我的问题里) - Rajdeep Siddhapura

2

检查键值对是否在请求中实际显示:

Chrome中,可以在以下位置找到: F12:开发者工具 > 网络选项卡 >您发送的任何请求> 在响应标题下查看源代码。

根据您的测试工作流程,如果您添加的任何键值对不在其中,则可能只需要清除浏览器缓存。 要验证浏览器是否使用最新代码,请检查页面来源,在Chrome中可以在以下位置找到: F12:开发者工具 > Sources选项卡 > YourJavascriptSrc.js 并检查您的代码。

但正如其他答案所说:

xhttp.setRequestHeader(key, value);

在发送请求前,应该向请求头添加一对键值对,确保将其放置在open()之后、send()之前。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接