跨域Ajax与Ext.Ajax.request

时间:2012-01-14 15:46:12

标签: ajax cross-domain sencha-touch jsonp

我似乎无法使用Ext.Ajax.request进行跨域ajax调用。看起来像ScriptTag:True没有任何效果。

这是我的代码:

            {
            xtype: 'button',
            text: 'Search',
            ui: 'confirm',
            handler: function() {
                var query = Ext.getCmp("textquery").getValue();
                Ext.Ajax.request({
                    url: 'http://example.com/?search='+query,
                    dataType: 'jsonp',
                    jsonp: 'jsonp_callback',
                    scriptTag: true,
                    success: function(e) {
                        var obj = Ext.decode(e.responseText);
                        var msg = obj;
                        var html = tpl.apply(msg);
                        resultPanel.update(html);
                    }
                });
            }

控制台日志告诉我:

XMLHttpRequest cannot load http://example.com/?search=test&_dc=1326551713063. Origin http://myapp.lo is not allowed by Access-Control-Allow-Origin.

使用jquery我做了同样的事情并且它有效,但我必须使用sencha touch。

              var formData = $("#callAjaxForm").serialize();

              $.ajax({
                url:"http://example.com/leksikonapi/",
                dataType: 'jsonp',
                jsonp: 'jsonp_callback',
                data: formData,
                success: onSuccess,
                error: onError
              });

我看不出两者之间有什么不同。

4 个答案:

答案 0 :(得分:4)

Sencha Touch 2的解决方案:使用Ext.data.JsonP

http://docs.sencha.com/touch/2-1/#!/api/Ext.data.JsonP

答案 1 :(得分:2)

尝试使用Ext.util.JSONP。我没有看到使用Ext.Ajax

在文档中执行jsonp的方法

答案 2 :(得分:1)

是的,没错。它被称为Same Origin Policy - 浏览器不会向除了javascript之外的任何域发出请求。如果您控制服务器,则可以使用CORS告诉浏览器发出请求。如果您不控制服务器,则必须编写服务器端代理。

答案 3 :(得分:0)

由于CORS(跨源资源共享)

,我在Chrome上遇到了同样的问题

浏览器将首先发送OPTIONS请求, 然后期望找回一些指示允许哪些来源的HTTP标头。

我通过在服务器端进行一些设置解决了这个问题 对于Ruby和Node.js服务器端,现在都运行良好。

Node.js(感谢the essay

// Enables CORS
var enableCORS = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
        res.send(200);
    }else{
        next();
    }
};
// enable CORS!
app.use(enableCORS);

Ruby(感谢essay

class ApplicationController < ActionController::Base
  before_filter :cors_preflight_check
  after_filter :cors_set_access_control_headers

  # For all responses in this controller, return the CORS access control headers.

  def cors_set_access_control_headers
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
    headers['Access-Control-Max-Age'] = "1728000"
  end

  # If this is a preflight OPTIONS request, then short-circuit the
  # request, return only the necessary headers and return an empty
  # text/plain.
  def cors_preflight_check
    if request.method == 'OPTIONS'
      headers['Access-Control-Allow-Origin'] = '*'
      headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
      headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
      headers['Access-Control-Max-Age'] = '1728000'

      render :text => '', :content_type => 'text/plain'
    end
  end
end