Python 套接字问题:无论使用何种浏览器,如何获取可靠的 POST 数据?
我用socket模块编写了一些Python+Ajax小程序(列在最后)来研究异步通信的COMET概念。
这个想法是允许浏览器通过我的python程序彼此实时发送消息。
技巧是让“GET messages/...”连接打开,等待消息回复。
我的问题主要在于我通过 socket.recv 获得的内容的可靠性...
当我 POST 时从 Firefox 中,它运行良好。
当我从 Chrome 或 IE 中发布时,我在 Python 中获得的“数据”是空的。
有人知道浏览器之间的这个问题吗?
某些浏览器是否会注入一些 EOF 或其他字符来终止“recv”的接收?
对于这个问题有任何已知的解决方案吗?
Python 中的 server.py:
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'
HTML+Javascript 中的 client.html:
<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>
I wrote small Python+Ajax programs (listed at the end) with socket module to study the COMET concept of asynchronous communications.
The idea is to allow browsers to send messages real time each others via my python program.
The trick is to let the "GET messages/..." connection opened waiting for a message to answer back.
My problem is mainly on the reliability of what I have via socket.recv...
When I POST from Firefox, it is working well.
When I POST from Chrome or IE, the "data" I get in Python is empty.
Does anybody know about this problem between browsers?
Are some browsers injecting some EOF or else characters killing the receiving of "recv"?
Is there any solution known to this problem?
The server.py in 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'
The client.html in 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您遇到的问题是
我推荐以下讲座:
请参阅下面的示例,了解可以处理帖子的工作 http 服务器
The problem you have is that
I recommend the following lectures:
See the example below for a working http server that can process posts
我建议在客户端使用 JS/Ajax 库,以消除代码出现跨浏览器问题的可能性。 出于同样的原因,我建议使用 python http 服务器库,例如 SimpleHTTPServer 或来自Twisted 如果前者不允许低级控制。
另一个想法 - 使用 Wireshark 之类的工具来检查浏览器发送的内容。
I would recommend using a JS/Ajax library on the client-side just to eliminate the possibility of cross-browser issues with your code. For the same reason I would recommend using a python http server library like SimpleHTTPServer or something from Twisted if the former does not allow low-level control.
Another idea - use something like Wireshark to check what's been sent by the browsers.
非常感谢弗洛里安,你的代码正在运行!!!!
我重用了该模板并使用 COMET 机制完成了main,它运行得更好
Chrome 和 Firefox 运行良好
IE仍然存在“长GET”系统的问题
当它收到 GET 的答案时,它不会停止重新执行循环来打印消息。
现在正在调查这个问题
这是我针对非常基本的 JQuery+Python 跨浏览器系统的更新代码。
Python 程序,基于 Florian 的代码:
以及使用 Jquery 压缩的 HTML:
Thank you very much Florian, your code is working!!!!
I reuse the template and complete the main with my COMET mecanism and it is working much better
Chrome and Firefox are working perfectly well
IE has still a problem with the "long GET" system
When it received the answer to the GET it does not stop to re executing the loop to print the messages.
Investigating right now the question
Here is my updated code for very basic JQuery+Python cross browser system.
The Python program, based on Florian's code:
And the HTML with Jquery compacted: