XMLHttpRequest用于本地文件

31

我有一个文件的路径,想要通过XMLHttpRequest对象将其发送到rest webservice服务器。Post请求如下:

var url = "http://localhost:8080/RestWSGS/jersey/gridsense";
 var boundary = "--------------" + (new Date).getTime();
  xmlHttp.open('POST', url, true);
  xmlHttp.onreadystatechange = function ()
  {
      if (this.readyState != 4)
        return;

      var result =this.responseText;
    document.write(result);
    };
  xmlHttp.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);

var  part ="";
 part += 'Content-Disposition: form-data; ';
  part += 'name="' + document.getElementById("filename").name + '" ; ';
  //alert(document.getElementById("filename").value);
  part += 'filename="'+ document.getElementById("filename").value +  '";\r\n';

  part += "Content-Type: application/xml";
  part += "\r\n\r\n"; // marks end of the headers part
  part += 'filename="'+ document.getElementById("filename").value +  '";\r\n';
  part+= data;
   var request = "--" + boundary + "\r\n";
  request+= part /* + "--" + boundary + "\r\n" */;
  request+= "--" + boundary + "--" + "\r\n";
  alert(request); 
  xmlHttp.send(request);  

我想发送的数据位于客户端本地磁盘上。 我想使用get方法获取它:

var str = document.getElementById("filename").value;


    var data;
    var xmlhttp1 = getNewHTTPObject();
    xmlhttp1.open("GET", 
    "file:///New Folder/" +document.getElementById("filename").value , false);

    xmlhttp1.send(null);
    alert('hi' + xmlhttp1.status);
    xmlhttp1.onreadystatechange = function()    {
        if (this.status == 0)
        {
            alert("resp " + this.responseText);
            data = this.responseText;
        }
    }

file://协议是不起作用的。如果我把文件放在客户端目录中并删除file:///,那么我至少可以看到xmlhttprequest打开并给出状态码200(我认为是好的!!)。我读到本地文件时要检查状态==0而不是readystatus==4,所以我这样做了,但它仍然将数据变量作为未定义,并且文件不会发送到服务器。最初当我将表单操作设为我的rest url时,上传很好。由于我没有使用html5,因此无法从input type=file元素获取文件对象。我想直接使用xmlhttprequest对象而不是表单元素来实现这一点。

请帮我解决这个问题,提供任何建议或提示。


即使我使用表单提交进行上传,如何使用web服务的返回值?这就是我需要使用xmlhttpRequest的原因。如果有人能建议如何使用操作的返回值,那就太好了!


也许你应该在JavaScript代码中使用<input type="file">来允许用户选择文件。这里是相应的RFC:http://www.faqs.org/rfcs/rfc1867.html。 - madhead
我正在使用它,但是它必须转换为URL才能分配给XMLHttpRequest,对吧?如果我查看输入元素的值,它只显示文件名而不是整个路径!无论如何,当我尝试将其转换为file:///格式的相对URL时,我感到困惑! - kavita
你应该一次性发送所有表单,而不是逐个字段发送。那么为什么你需要特别获取那个文件呢?http://www.ajaxf1.com/tutorial/ajax-file-upload-tutorial.html - madhead
1
可以通过直接表单提交来实现,正如我在问题中已经提到的那样,但是无法使用XMLHttpRequest来实现,因为创建请求时必须从本地文件读取数据。如果使用HTML5,可以使用element.file[0]元素来上传它!但是无法使用XMLHttpRequest来实现。 - kavita
3个回答

24

历史上,JavaScript 通常无法查询本地文件(或者不应该允许这样做,否则就存在安全漏洞)。

只有在特定的安全设置下,才能够绕过此限制来实现访问本地文件。通常需要更改浏览器属性或请求文件访问权限以开发浏览器扩展程序(例如 Chrome 或 Firefox)。

另一种绕过此限制的方法是搭建本地 Web 服务器,并声明虚拟主机。通过这种方式可以使用 AJAX 请求获取本地文件。这种技巧非常常见,旨在在进行本地开发的同时复制生产系统。可以使用像 Jetty 这样的轻量级 Web 服务器。

(还有一个烦人的问题是,某些浏览器 - 至少是一些相对较旧的 Firefox 版本,例如 3.6.x - 有时会返回正面的错误代码,如 200,即使它们的内部安全策略已经阻止了请求。这可能会让你感到困惑…)。

最后,新的 HTML5 API 提供了一些新的构造函数来访问本地文件。可以参考以下链接:

其他 SO 问题也提供了额外的指针:


1
只要文件位于HTML文件的操作路径中,您可以加载本地文件(例如JSON)。我想通过XHR使其像jQuery一样工作。 - FlavorScape
以下是一些与JavaScript中XHR和fetch相关的附加解决方案,适用于初学者:https://dev59.com/6FUL5IYBdhLWcg3wqZeb#50007208 - V. Rubinetti

5
我使用一个iframe。
<div class="item" onclick="page(event)">HTML5</div>

<iframe id="page" src="">

function page(e) {
    trigger = e.currentTarget.innerHTML;
    docname = new String(trigger + ".txt");
    document.getElementById("page").src = docname;
}

2
只是好奇:HTML标签前面的句点是什么意思?例如:<.div> <.iframe>?你的JavaScript代码中也有HTML标签。 - Michael Scheper
1
@MichaelScheper -- 这很可能是为了在这里展示代码而尝试进行格式化,但后来被编辑成代码块而没有删除那些部分。现在已经修复。 - John Weisz

-4
我找到了一个简单的解决方案。 你需要在本地URL“file:///..”后面添加“?application/xhtml+xml”。

5
一些带有解释的例子会很棒。 - Nilambar Sharma
2
这根本不是解决方案,如果您使用的是本地机器,则该参数根本无效。如果您能提供一个示例代码,那就更好了。 - Erick

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