获得用户可靠的 POST 数据,无论用户使用什么浏览器,通常需要考虑以下几个方面:
1、问题背景
在Python socket中,当使用AJAX程序来获取通过COMET异步通信发送的消息时,在Chrome或IE浏览器中,获取POST数据总是为空。而在Firefox浏览器中却可以正常工作。 以下详细描述了问题背景:
- 编写了一个简单的Python + Ajax程序,使用socket模块来研究COMET异步通信的概念。
- 这样做的目的是允许浏览器通过我的Python程序实时向对方发送消息。
- 诀窍在于让“GET消息/...”连接打开,等待消息来应答。
- 问题主要是在于通过socket.recv获取的可靠性上。
- 从Firefox发布时,工作正常。
- 但从Chrome或IE发布时,在Python中获得的“数据”为空。
2、解决方案
2.1 Python服务器代码
以下是如何解决该问题的Python服务器代码:
import socket
connected = {}
def inRequest(text):
content = ''
if text[0:3] == 'GET':
method = 'GET'
else:
method = 'POST'
k = len(text) - 1
while k > 0 and text[k] != '\n' and text[k] != '\r':
k = k - 1
content = text[k + 1:]
text = text[text.index(' ') + 1:]
url = text[:text.index(' ')]
return {"method": method, "url": url, "content": content}
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.bind(('', 80))
mySocket.listen(10)
while True:
channel, details = mySocket.accept()
data = channel.recv(4096)
req = inRequest(data)
url = req["url"]
if url == "/client.html" or url == "/clientIE.html":
f = open('C:\async\' + url)
channel.send('HTTP/1.1 200 OK\n\n' + f.read())
f.close()
channel.close()
elif '/messages' in url:
if req["method"] == 'POST':
target = url[10:]
if target in connected:
connected[target].send(
"HTTP/1.1 200 OK\n\n" + req["content"])
print(req["content"] + " sent to " + target)
connected[target].close()
channel.close()
elif req["method"] == 'GET':
user = url[10:]
connected[user] = channel
print(user + ' is connected')
2.2 HTML+Javascript客户端代码
以下是如何解决该问题的HTML + Javascript客户端代码:
<html>
<head>
<script>
var user = ''
function post(el) {
if (window.XMLHttpRequest) {
var text = el.value
var req = new XMLHttpRequest()
el.value = ''
var target = document.getElementById('to').value
}
else if (window.ActiveXObject) {
var text = el.content
var req = new ActiveXObject("Microsoft.XMLHTTP")
el.content = ''
}
else
return
req.open('POST', 'messages/' + target, true)
req.send(text)
}
function get(u) {
if (user == '')
user = u.value
var req = new XMLHttpRequest()
req.open('GET', 'messages/' + user, true)
req.onload = function () {
var message = document.createElement('p')
message.innerHTML = req.responseText
document.getElementById('messages').appendChild(message)
get(user)
}
req.send(null)
}
</script>
</head>
<body>
<span>From</span>
<input id="user"/>
<input type="button" value="sign in" onclick="get(document.getElementById('user'))"/>
<span>To</span>
<input id="to"/>
<span>:</span>
<input id="message"/>
<input type="button" value="post" onclick="post(document.getElementById('message'))"/>
<div id="messages">
</div>
</body>
</html>
2.3 其他解决方案
- 确保你的TCP套接字处理读取了足够的数据。
- 确保您的HTTP处理是完整的。
- 查看以下讲座和示例:
- rfc2616
- Stevens的套接字网络API
- 一个可以处理帖子的工作http服务器的例子
- 通过上述方法,你可以确保无论用户使用什么浏览器,POST 数据都能被可靠地接收和处理。