javascript - JSONP - 触发完成、成功、错误 Ajax 调用

标签 javascript jquery ruby-on-rails ajax

好吧,我已经为此奋斗了几个小时。

我手动返回不同的状态代码...如果状态为 200,则表示成功并完成。

但我已经尝试了很多 400 代码示例:400、401、403、404 来触发错误,但永远无法正常工作

当我传递除状态 200 之外的任何内容时,它只会重新加载页面...但如果状态为 200,它也会登录并提醒完成...

(function( $ ) {
  var Core = Core || {};
  Core = {
    init: function (){
    },
    api: {
      submit: function( ajax_url, ajax_data, callback ){
        var auth_token = '';
        if( Core.auth.isAuthenticated() ) {
          auth_token = Core.auth.authToken.get();
        }
        $.ajax({
          type: "GET",
          dataType: "jsonp",
          // test
          url: "http://192.168.1.65:3000/" + ajax_url,
          // live
          //url: "http://www.customsite.com/" + ajax_url,
          cache: false,
          //data: ajax_data,
          data: 'auth_token='+ auth_token + '&' + ajax_data,
          success: function(data) {
            if(typeof callback.onSuccess == 'function'){
              callback.onSuccess.call(this, data);
            }
          },
          error: function(data){
            if(typeof callback.onError == 'function'){
              callback.onError.call(this, data);
            }
          },
          complete: function(data){
            if(typeof callback.onComplete == 'function'){
              callback.onComplete.call(this, data);
            }
          }
        });
      }
    }
  };

  $( Core.init );
  window.Core = Core;
})(jQuery);

表单提交

authenticate: {
  onSubmit: function(form_obj) {
    var ajax_url = form_obj.attr('action'),
        ajax_data = form_obj.serialize();
    Core.api.submit( ajax_url, ajax_data,
      {
        onSuccess: Core.login.authenticate.onSuccess,
        onError: Core.login.authenticate.onError,
        onComplete: Core.login.authenticate.onComplete
      }
    );
  },

  onSuccess: function(data) {
    Core.auth.authToken.set(data.access_token, 30);
    window.location = 'index.html';
  },

  onError: function(data) {
      alert('ERROR');
  },


  onComplete: function(data) {
      alert('Complete');
  }
}

rails 应用:

  def create
    resource = User.find_for_database_authentication(:email => params[:user][:email])
    if resource.valid_password?(params[:user][:password])
      resource.reset_authentication_token!
      render :json => {:access_token => resource.authentication_token, :token_type => "persistant"}, :callback => params[:callback], :status => 200
    else
      render :json => {:error => "invalid_grant"}, :callback => params[:callback], :status => 404
    end
  end

最佳答案

您正在发出 JSONP 请求,这是跨域“Ajax”的一种形式。阅读What is JSONP all about?在 StackOverflow 上了解它的工作原理。

简短描述:JSONP 使用 <script src="your URL here"></script>标记触发 JavaScript 文件的下载。由于它是一个常规的 SCRIPT 元素,任何非 200 HTTP 响应都会触发浏览器中该元素的“onerror”回调。来自 Rails 应用程序的类似 REST 的响应正在破坏浏览器上的错误处理。 jQuery 中的 JSONP 请求具有非常有限的错误处理。如果发出 JSONP 请求,您始终需要呈现 200 OK响应。

如果您想要类似 REST 的响应,我建议您使用一些额外的 JSON 包装您的实际 HTTP 响应:

{
    "response": {
        "status": 401,
        "data": {
            ...
        }
    }
}

然后您的成功处理程序将必须智能地解析响应:

success: function(data) {
    if (data.response.status === 200 && callback.onSuccess) {
        callback.onSuccess.call(this, data.response.data);
    }
    else if (data.response.status >= 400 && callback.onError) {
        callback.onError.call(this, data.response.data.error);
    }

    if (callback.onComplete) {
        callback.onComplete.call(this, data.response.data);
    }
}


authenticate: {
  onSubmit: function(form_obj) {
    var ajax_url = form_obj.attr('action'),
        ajax_data = form_obj.serialize();
    Core.api.submit( ajax_url, ajax_data,
      {
        onSuccess: Core.login.authenticate.onSuccess,
        onError: Core.login.authenticate.onError,
        onComplete: Core.login.authenticate.onComplete
      }
    );
  },

  onSuccess: function(data) {
    Core.auth.authToken.set(data.access_token, 30);
    window.location = 'index.html';
  },

  onError: function(data) {
      alert(data);
  },

  onComplete: function(data) {
  }
}

对 Rails Controller 的更改:

def create
  resource = User.find_for_database_authentication(:email => params[:user][:email])

  if resource.valid_password?(params[:user][:password])
    resource.reset_authentication_token!

    render :json => {
      :response => {
        :status => 200,
        :data => {:access_token => resource.authentication_token, :token_type => "persistant"}
        }
      } 
    }, :callback => params[:callback]


  else
    render :json => {
      :response => {
        :status => 401,
        :data => {
          :error => "invalid_grant"
        }
      }
    }, :callback => params[:callback]
  end
end

关于javascript - JSONP - 触发完成、成功、错误 Ajax 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27512463/

相关文章:

ruby-on-rails - 使用 Dockerfile 克隆私有(private) git gem 存储库的最佳方法

javascript - 在 Canvas 中心写(0,0)-HTML5

javascript - 在 JavaScript 中遍历嵌套数组

javascript - GAS - onChange 触发器(从事件工作表获取值)并写入另一个电子表格

javascript - d3 更改单击的节点文本的类

jquery - 带有我的标题的外部网站

JavaScript 正则表达式 - 匹配除之外的所有内容

javascript - 为 href 属性获取相同的值

ruby-on-rails - 语法错误意外的tANDOP on rails 3教程

html - 居中引导 3 导航栏