用Javascript直接发布MIME Multipart数据的服务器错误
Server error posting MIME Multipart data directly with Javascript
我试图直接在Javascript中构建多部分表单数据,以便将我的数据发送到服务器。我知道有Ajax表单插件,但我真的认为他们不适合我的需要,因为我将在浏览器中创建二进制数据,并发送它,如果它是一个文件提交(服务器我将发布到需要它的方式)。
我现在的问题是,构建文本多部分MIME数据的最简单示例在服务器端失败,并出现错误:
500 Internal Server Error: Invalid boundary in multipart form
我试图将代码减少到最低限度:在这个main.html(这是稍后在服务器代码中引用的名称)中,都有一个html表单以html非ajax方式提交文本,还有一个Javascript函数试图复制XmlHttprequest:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Posting MIME Multipart directly in Javascript</title>
<script>
function sendMimeMultipart(url, data) {
boundary = '---------------------------1504702169761927311267328916'
xhr = new XMLHttpRequest();
xhr.open("POST", url);
//Build the MIME POST request.
var body = "--" + boundary + "'r'n";
body += 'Content-Disposition: form-data; name="contents"'r'n'r'n';
body += data+"'r'n";
body += "--" + boundary + "--"+"'r'n";
var fileSize = body.length
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
xhr.setRequestHeader("Content-Length", fileSize);
xhr.send(body);
return true;
}
function sendData() {
sendMimeMultipart('http://localhost:8080/myhandler', "Hello World!");
}
</script>
</head>
<body onload='sendData()'>
<form action = "myhandler" method = "post" enctype = "multipart/form-data">
<input type = "text" name = "contents">
<input type = "submit">
</form>
</body>
</html>
这是当使用表单时到达服务器的请求对象:
Request: POST /myhandler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Connection: keep-alive
Content-Length: 187
Content-Type: multipart/form-data;
boundary=---------------------------18171295601131570933197493099
Host: localhost:8080
Keep-Alive: 115
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20)
Gecko/20110803 Firefox/3.6.20
-----------------------------18171295601131570933197493099
Content-Disposition: form-data; name="contents"
Hello World!
-----------------------------18171295601131570933197493099--
当使用Javascript函数(sendMimeMultipart)时,这是到达服务器的请求对象:
Request: POST /myhandler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 185
Content-Type: multipart/form-data; charset=UTF-8,
boundary=---------------------------1504702169761927311267328916
Host: localhost:8080
Keep-Alive: 115
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20)
Gecko/20110803 Firefox/3.6.20
-----------------------------1504702169761927311267328916
Content-Disposition: form-data; name="contents"
Hello World!
-----------------------------1504702169761927311267328916--
Content-Length中2个字节的差异是因为浏览器随机生成边界,有时更长,有时更短。在这种情况下,它长一个字符,这就是两个边界出现的两个字节差的原因。
我不认为服务器与此有很大关系,只是以防我发布服务器端代码。这是一个Appengine代码片段,仅供本地主机使用;对"localhost:8080/myhandler"的调用检索浏览器发布的"contents"的值,并将其存储在一个全局变量中。之后,对"localhost:8080/show"的调用显示先前检索到的文本。如前所述,如果我们使用表单发送数据,文本内容将被正确保存,并且"show"处理程序将显示它。然而,如果我们使用Javascript,代码行:
contents = self.request.get("contents")
在MyHandler(代码如下)中,产生错误。
服务器代码:
import cgi
import datetime
import logging
import os
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
from google.appengine.ext.webapp import template
from os import environ
contents=''
class mein(webapp.RequestHandler):
def get(self):
template_values = {}
path = os.path.join(os.path.dirname(__file__), 'templates/main.html')
self.response.out.write(template.render(path, template_values))
class MyHandler(webapp.RequestHandler):
def post(self):
global contents
contents = self.request.get("contents")
class Show(webapp.RequestHandler):
def get(self):
global contents
self.response.headers['Content-Type'] = "text/plain"
self.response.out.write(contents)
application = webapp.WSGIApplication([
('/', mein),
('/myhandler', MyHandler),
('/show', Show)
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
知道为什么会失败吗?我已经尝试了无数种不同的方法,但我似乎无法使它起作用,也不明白为什么它不起作用!
事先非常感谢你的意见和帮助。
祝一切顺利:
哈维尔
我在尝试手动构建http文件上传时遇到了相同的错误消息。我通过在Content-Type头文件中用分号(;)替换逗号(,)来实现它。在您的情况下,通过替换:
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
:
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary);
这似乎与Python后端有关,因为我在Django(Python)中遇到了同样的问题,当我在PHP测试服务器上调试它时,逗号和分号都有效。
最后,RFC1867中的例子使用逗号,所以最后我不确定什么是正确的方法,但分号为我解决了这个问题。
- 使用谷歌应用程序脚本将服务器端数据表返回到客户端
- 如何配置分析以将数据发送到我自己的服务器
- 如何将Knockout.JS与服务器已经在DOM中呈现的数据同步
- React路由器服务器端渲染和ajax获取数据
- 在HTML页面上显示node.js服务器中的数据
- 从服务器获取数据并在选择控件中使用ng选项无法显示选项
- 如何在服务器上保存数据以备日后使用
- 将JSON数据从服务器加载到knockout.jsobservable中
- 如何在Angular.js中循环动态添加Fields并获取数据并将其发送到服务器
- Highcharts可以从服务器加载数据,但不能更新
- JQGrid使用服务器编辑后的更新数据刷新数据
- 返回之前获取数据服务器端
- 验证后 JSON 数据服务器端
- Angular E2E 测试数据:ngMockE2E 或测试数据服务器
- 如何在 Meteor 中存储特定于客户端的数据服务器端
- 在我们的数据服务器上保存谷歌地图中的gData
- 如何从服务器接收数据(服务器用java编写,到HTML文件)
- 如何发送数据服务器(JAVA编写)到客户端(Node.js编写)
- 如何访问Backbone Fetch数据服务器端
- 发布数据服务器端并在提交表单时执行javascript代码