Python电子邮件CGI脚本发送重复邮件
我最近在尝试用Python写一个CGI脚本来发送电子邮件(托管在一个商业网站上 - 123reg),但遇到了一个问题:每次我从浏览器运行这个脚本时,它都会发送两封完全相同的邮件。
发送邮件的代码肯定只执行了一次,没有任何循环会导致它执行两次,我也绝对没有点击按钮两次。没有出现任何异常,"成功"页面也正常发送到浏览器。
最奇怪的是,当我把打印结果页面的代码注释掉(这个代码很简单,只是连续三条打印语句),然后用一个虚假的打印语句替代(print "Content-type: text/plain\n\ntest"),它就正常工作,只发送一封邮件。
我试着在网上搜索这个问题,但没有找到解决办法。
我快要抓狂了,因为这个问题对我来说完全没有道理。我很确定问题出在我的脚本上,因为当我注释掉那些打印语句时,它 inexplicably 就能正常工作。
如果有人能帮忙,我会非常感激,谢谢。
编辑:
这是注释掉后能解决问题的代码:
print "Content-type: text/html"
print
print page
编辑:
发送电子邮件的代码:
#send_email function: sends message from from_addr, assumes valid input
def send_email(from_addr, message):
#form the email headers/text:
email = "From: " + from_addr + "\n"
email += "To: " + TO[0] + "\n"
email += "Subject: " + SUBJECT + "\n"
email += "\n"
email += message
#return true for success, false for failure:
try:
server = smtplib.SMTP(SERVER)
server.sendmail(from_addr, TO, email)
server.quit()
return True;
except smtplib.SMTPException:
return False;
#end of send_email function
我本来想发一下格式化页面变量的代码,但它只是从一个文件中读取,格式化一个字符串并返回这个字符串。没什么特别的。
编辑:
好的,我注释掉了create_page函数中的文件输入输出代码,这解决了问题,但我不明白为什么,也不知道该怎么修改它才能正常工作。
当我发现注释掉打印语句能解决问题时,create_page函数和文件输入输出仍然在执行。
这是我注释掉之前的文件输入输出代码(它在create_page函数的最开始,后面的代码只是修改页面字符串,然后返回它):
#read the template from the file:
frame_f = open(FRAME)
page = frame_f.read()
frame_f.close()
编辑:
我刚刚通过直接把文件文本复制粘贴到我的源文件中的一个字符串里来替代文件输入输出,所以现在不再有文件输入输出了。但这仍然没有解决问题。此时我唯一的理论就是电脑就是讨厌我……
编辑:
我得把这个发在这里,因为stackoverflow不让我回答自己的问题,因为我在这里是个新手……
编辑:
好的,我现在把它作为一个实际的答案发上来了。
3 个回答
如果你在Javascript中使用了一个空的src或者用"#"作为src,情况会是一样的:
<script type="text/javascript" src="#"></script>
对于CSS链接,如果href是空的,可能也会出现类似的情况。我没有遇到过这种情况,但我觉得应该会有同样的表现。
如果你能发更多的代码就好了。不过“page”这个变量里面是否有代码,会让邮件服务器再执行一次,或者导致页面刷新,从而让邮件再发送一次呢?
问题解决了!
原来一直是浏览器的问题。我之前没有早点发现是因为我很久以前在Firefox和Chrome上测试过,想排除浏览器的影响,但结果发现这两个浏览器都有同样的bug。
当服务器日志终于更新时,我意识到发生了什么。我发现经常会有GET请求在1秒后紧接着又出现一个GET请求。我在网上查了一下,发现了这个:
是什么导致Firefox在通过POST方法提交表单后发出GET请求?
原来,如果你有一个img标签,但src属性是空的,比如:
<img src=""/>
(我有一些javascript代码会修改这个标签),Firefox就会发出一个重复的GET请求,而不是请求这个图片。结果发现Chrome也有同样的问题。这也解释了为什么这个问题只在我尝试包含我的html模板时出现。