jquery.form和跨域请求

kik*_*ito 3 javascript ajax jquery jquery-plugins cross-domain

我很难尝试使用跨域请求创建jquery.form.我遇到了Firefox和Chrome的问题(甚至还没试过IE).

说明:我的整个站点位于http://www.mysite.com内.但是,我的联系表单位于另一台服务器上,由http://contact.mysite.com引用.我认为将它放在子域上会避开有关跨域请求的问题,但显然它没有.http://contact.mysite.comSinatra实施.

我的javascript设置没什么特别的.表单的操作指向http://contact.mysite.com,方法是POST:

<form id="contact" action="http://contact.mysite.com/" method="post">
Run Code Online (Sandbox Code Playgroud)

jquery.form配置了一个ajaxForm调用:

$(document).ready(function() {

  $('#contact').ajaxForm({
    success: function() { $('#success').fadeIn("slow"); },
    error: function() {  $('#error').fadeIn("slow"); }
  });

});
Run Code Online (Sandbox Code Playgroud)

我遇到的第一个问题是使用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
Run Code Online (Sandbox Code Playgroud)

使用jquery 1.4.3,我在firebug上看到一个OPTIONS请求,后跟一个POST请求(状态200.发送了电子邮件).使用jquery 1.3.2或1.5,仅显示OPTIONS请求(未发送电子邮件).

尽管如此,error我试过的所有版本的jquery总是触发回调.我追溯到$.ajax(...)调用,所以我不确定这个问题是来自jquery.form还是jquery本身.

我尝试记录来自错误的信息:

$('#contact').ajaxForm({
  success: function() { $('#success').fadeIn("slow"); },
  error: function(jqXHR, textStatus, errorThrown) {
    console.log(jqXHR.status);
    console.log(jqXHR.statusText);
  }
}); 
Run Code Online (Sandbox Code Playgroud)

在jquery 1.4.3上输出(发送OPTIONS和POST请求后,状态为200):

0
(empty string)
Run Code Online (Sandbox Code Playgroud)

在jquery 1.5上输出(在OPTIONS返回200状态后;从不发送POST)

302
error
Run Code Online (Sandbox Code Playgroud)

我真的迷失在这里.

  • 有没有一个处理这个的插件?
  • 我在某处遗漏了什么吗?

任何帮助将不胜感激.

Ale*_*dev 8

AJAX请求不能跨域执行(UPD:不再是真的,所有现代浏览器都支持CORS),但您可以使用JSONP.虽然JSONP可以跨域工作,但它不能用于POST请求,您需要将表单的方法更改为get并使用它:

$('#contact').ajaxForm({
  success: function() { $('#success').fadeIn("slow"); },
  error: function() {  $('#error').fadeIn("slow"); },
  dataType: 'jsonp'
});
Run Code Online (Sandbox Code Playgroud)

上面的解决方案依赖于您的服务器响应有效的jsonp响应,否则success将不执行处理程序.例如:response.write(request.callback + '(' + result.to_json + ')')


最新版本的jQuery可以在没有ajaxForm插件的情况下序列化表单.如果您不需要文件上传,可以使用:

$('form').submit(function() {
  var url = $(this).attr('action')
  var params = $(this).serialize()
  $.getJSON(url + '?' + params + "&callback=?", function(data) {
    // success
  })
  return false
});
Run Code Online (Sandbox Code Playgroud)