我在尝试使用跨域请求制作jquery.form时遇到了困难。我在Firefox和Chrome上遇到问题(甚至还没有尝试IE)。
说明:我的整个网站都位于http://www.mysite.com内。但是,我的联系表在另一台服务器上,由http://contact.mysite.com引用。我认为将其放在子域上可以避开有关跨域请求的问题,但显然没有。在Sinatra中实现了http://contact.mysite.com。
我的javascript设置没什么花哨的。表单的操作指向http://contact.mysite.com,方法为POST:
<form id="contact" action="http://contact.mysite.com/" method="post">
使用ajaxForm调用配置jquery.form :
$(document).ready(function() { $('#contact').ajaxForm({ success: function() { $('#success').fadeIn("slow"); }, error: function() { $('#error').fadeIn("slow"); } }); });
我遇到的第一个问题是Firefox 3.5-显然,它发送了一个OPTIONS请求,期望服务器提供特定的答案。我用这个问题来配置我的Sinatra应用程序,使其达到了预期的效果(似乎最新版本的sinatra包含一个选项动词):
require 'rubygems' require 'sinatra' require 'pony' # patch sinatra so it handles options requests - see https://stackoverflow.com/questions/4351904/sinatra-options-http-verb configure do class << Sinatra::Base def options(path, opts={}, &block) route 'OPTIONS', path, opts, &block end end Sinatra::Delegator.delegate :options end # respond to options requests so that firefox can do cross-domain ajax requests options '/' do response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Methods'] = 'POST' response['Access-Control-Max-Age'] = '2592000' end post '/' do # use Pony to send an email Pony.mail(...) end
使用jQuery 1.4.3,我在firebug上看到了一个OPTIONS请求和一个POST请求(状态200。已发送电子邮件)。使用jquery 1.3.2或1.5时,仅显示OPTIONS请求(未发送电子邮件)。
但是,error回调总是在我尝试过的所有版本的jQuery中触发。我将其追溯到$.ajax(...)调用,所以我不确定这个问题是来自jquery.form还是jquery本身。
error
$.ajax(...)
我尝试注销来自错误的信息:
$('#contact').ajaxForm({ success: function() { $('#success').fadeIn("slow"); }, error: function(jqXHR, textStatus, errorThrown) { console.log(jqXHR.status); console.log(jqXHR.statusText); } });
在jquery 1.4.3上的输出(在发送OPTIONS&POST请求之后,状态均为200):
0 (empty string)
在jQuery 1.5上输出(在OPTIONS返回200状态后;从不发送POST)
302 error
我真的在这里迷路了。
任何帮助将不胜感激。
无法跨域执行AJAX请求( UPD: 不再适用,所有现代浏览器都支持CORS),但是您可以改用JSONP。尽管JSONP可以跨域工作,但是它不能用于POST请求,并且您需要将表单的方法更改为get并使用此方法:
get
$('#contact').ajaxForm({ success: function() { $('#success').fadeIn("slow"); }, error: function() { $('#error').fadeIn("slow"); }, dataType: 'jsonp' });
上面的解决方案依赖于您的服务器以有效的jsonp响应进行响应,否则success将不执行处理程序。例如:response.write(request.callback + '(' + result.to_json + ')')
success
response.write(request.callback + '(' + result.to_json + ')')
jQuery的最新版本可以在没有ajaxForm插件的情况下序列化表单。如果不需要文件上传,可以使用以下命令:
ajaxForm
$('form').submit(function() { var url = $(this).attr('action') var params = $(this).serialize() $.getJSON(url + '?' + params + "&callback=?", function(data) { // success }) return false });