jquery.form 和跨域请求

jquery.form and cross-domain requests(jquery.form 和跨域请求)
本文介绍了jquery.form 和跨域请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我很难尝试使用跨域制作 jquery.form要求.我在使用 Firefox 和 Chrome 时遇到问题(甚至还没有尝试过 IE).

I'm having a hard time trying to make jquery.form with a cross-domain request. I'm having issues with Firefox and Chrome (didn't even try IE yet).

说明:我的整个网站都位于 http://www.mysite.com 内.但是,我的联系表单在另一台服务器上,由 http://contact.mysite.com 引用.我认为将其放在子域上会回避有关跨域请求的问题,但显然事实并非如此.http://contact.mysite.com 在 Sinatra.

Explanation: my whole site is located inside http://www.mysite.com. However, my contact form is on another server, referenced by http://contact.mysite.com . I thought that putting it on a subdomain would sidestep the issues regarding cross-domain requests, but apparently it didn't. http://contact.mysite.com is implemented in Sinatra.

我的 javascript 设置没有什么花哨的.表单的action指向http://contact.mysite.com,方法是POST:

My javascript setup is nothing fancy. The form's action points to http://contact.mysite.com and the method is POST:

<form id="contact" action="http://contact.mysite.com/" method="post">

jquery.form 配置有 ajaxForm 调用:

jquery.form is configured with an ajaxForm call:

$(document).ready(function() {

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

});

我遇到的第一个问题是 Firefox 3.5 - 显然它发送了一个 OPTIONS 请求,期望服务器提供特定的答案.我使用 this question 来配置我的 Sinatra 应用程序,使其达到预期效果(似乎更多最新版本的 sinatra 包含一个选项动词):

The first problem I encountered was with Firefox 3.5 - apparently it sends an OPTIONS request expecting an specific answer from the server. I used this question to configure my Sinatra app so it did what was expected (it seems that more recent versions of sinatra include an options verb):

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 请求(未发送电子邮件).

With jquery 1.4.3, I saw on firebug an OPTIONS request followed by a POST request (status 200. The email was sent). With jquery 1.3.2 or 1.5, only the OPTIONS request was shown (the email was not sent).

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

Nevertheless, the error callback is always fired with all versions of jquery I tried. I traced that down to the $.ajax(...) call, so I'm not sure of whether this problem comes from jquery.form or jquery itself.

我尝试注销来自错误的信息:

I tried logging out the information coming from the error:

$('#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):

Output on jquery 1.4.3 (after the OPTIONS & POST requests are sent, both with status 200):

0
(empty string)

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

Output on jquery 1.5 (after OPTIONS returns with a 200 status; POST is never sent)

302
error

我真的迷路了.

  • 是否有插件可以处理这个问题?
  • 我是否在某处遗漏了什么?

任何帮助将不胜感激.

推荐答案

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

AJAX requests cannot be executed cross-domain (UPD: not true anymore, all modern browsers support CORS), but you can use JSONP instead. Although JSONP works cross-domain, it can't be used for POST requests, and you'll need to change you form's method to get and use this:

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

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

The solution above relies on your server responding with a valid jsonp response, otherwise success handler won't be executed. e.g: response.write(request.callback + '(' + result.to_json + ')')

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

Latest versions of jQuery can serialize forms without the ajaxForm plugin. If you don't need file uploads you can use this:

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

这篇关于jquery.form 和跨域请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Google apps script get range of bytes from binary file(谷歌应用程序脚本从二进制文件中获取字节范围)
Sending Multiple attachments with Google Script from Google Drive(使用 Google 脚本从 Google Drive 发送多个附件)
Distributing Google Apps Scripts for Sheets in your company network(在您的公司网络中分发适用于表格的 Google Apps 脚本)
Upload file to my google drive from anyone using javascript(使用 javascript 将文件从任何人上传到我的谷歌驱动器)
quot;Shared Drivequot; support in Google Apps Script(“共享驱动器Google Apps 脚本中的支持)
Angular 2+ HTTP POST and GDrive API. Resumable file upload with name(Angular 2+ HTTP POST 和 GDrive API.带名称的可恢复文件上传)