【问题标题】:jQuery Cross Domain AjaxjQuery 跨域 Ajax
【发布时间】:2013-06-04 01:54:43
【问题描述】:

我的ajax代码是

$.ajax({
    type: 'GET',
    dataType: "jsonp",
    processData: false,
    crossDomain: true,
    jsonp: false,
    url: "http://someotherdomain.com/service.svc",
    success: function (responseData, textStatus, jqXHR) {
        console.log("in");
    },
    error: function (responseData, textStatus, errorThrown) {
        alert('POST failed.');
    }
});

这是一个跨域ajax请求。

我得到了对该请求的正确响应,在使用 firebug 检查时我可以看到该响应。

这是我在萤火虫响应和通过网络浏览器访问此网址时得到的响应

{"AuthenticateUserResult":"{\"PKPersonId\":1234,\"Salutation\":null,\"FirstName\":\"Miqdad\",\"LastName\":\"Kumar\",\"Designation\":null,\"Profile\":\"\",\"PhotoPath\":\"\/UploadFiles\/\"}"}

但是我遇到了错误

SyntaxError: invalid label

{"AuthenticateUserResult":"{\"PKPersonId\":8970,\"Salutation\

我是否需要使用任何其他方法才能使其正常工作。我想在 phonegap+jquery 移动应用中实现这个。

另外,我没有任何访问网络服务的权限

如果我禁用 chrome 网络安全,它可以正常工作

【问题讨论】:

  • 使用这三个选项是否有任何理由,或者您是否只是将它们插入以查看它们是否有效:processData:false,crossDomain:true,jsonp: false, processData 不需要,因为#1您没有发送任何数据,而#2 对 jsonp 请求没有任何意义。 crossDomain:true 几乎从不需要,唯一的情况是,如果您想执行同源请求,同时将其视为跨域请求。由于您正在发出跨域请求,因此默认情况下它已经是真实的。 jsonp:false 不应该在没有 jsonpCallback:"callback" 的情况下使用。
  • 不...这是我为测试添加的。这个跨域请求就是我使用这些代码的原因;)
  • 查看更新的评论,抱歉。这三个选项对您提出的请求没有任何意义。
  • 如果有的话,你需要发出一个 CORS 请求,但这只有在 web 服务支持 CORS 时才会起作用,而且鉴于提供的内容,我们无法判断它是否确实如此。
  • 首先,删除这三个选项并再次尝试请求。你成功了吗? (错误回调可以去掉,jsonp请求不会触发)

标签: jquery ajax json jquery-mobile cordova


【解决方案1】:

看起来内部 JSON 结构是作为字符串传递的。您必须再次 JSON.parse() 才能将该数据作为对象获取。

try {
  responseData = JSON.parse(responseData);
}
catch (e) {}

编辑: 请尝试以下操作:

$.ajax({
    type: 'GET',
    dataType: "json",
    url: "http://someotherdomain.com/service.svc",
    success: function (responseData, textStatus, jqXHR) {
        console.log("in");
        var data = JSON.parse(responseData['AuthenticateUserResult']);
        console.log(data);
    },
    error: function (responseData, textStatus, errorThrown) {
        alert('POST failed.');
    }
});

【讨论】:

  • 但脚本没有到达success methode 内部。那么我怎么能抓住这个?
  • 我也试过了。但是那个时候ajax错误方法正在触发并且也没有得到任何响应。
  • 抱歉,该 api 是私有的,我已粘贴来自相关 api 本身的响应
  • 我的脚本没有达到内部成功method
  • 它不会到达它,因为 jQuery 尝试自动解析 JSON,但它失败了。 stackoverflow.com/questions/16989505/jquery-cross-domain-ajax/…
【解决方案2】:

不幸的是,这个 Web 服务似乎返回了包含另一个 JSON 的 JSON - 解析内部 JSON 的内容是成功的。解决方案很丑陋,但对我有用。 JSON.parse(...) 尝试转换整个字符串并失败。假设您总是得到以{"AuthenticateUserResult": 开头的答案,并且有趣的数据在此之后,请尝试:

$.ajax({
    type: 'GET',
    dataType: "text",
    crossDomain: true,
    url: "http://someotherdomain.com/service.svc",
    success: function (responseData, textStatus, jqXHR) {
        var authResult = JSON.parse(
            responseData.replace(
                '{"AuthenticateUserResult":"', ''
            ).replace('}"}', '}')
        );
        console.log("in");
    },
    error: function (responseData, textStatus, errorThrown) {
        alert('POST failed.');
    }
});

dataType 必须是 text 非常重要,以防止自动解析您从 Web 服务接收到的格式错误的 JSON。

基本上,我通过删除最上面的大括号和键 AuthenticateUserResult 以及前导和尾随引号来消除外部 JSON。结果是格式良好的 JSON,可供解析。

【讨论】:

  • 我也试过这个...但是我的脚本没有达到成功方法
  • 到达错误方法了吗? responseData、textStatus 和 errorThrown 中有什么?假设您已将 dataType 设置为 text
  • 那么,您是否尝试过提醒 textStatus、responseData 和 errorThrown?
  • 我知道这不会是最终的解决方案,但我们需要向前迈进。您说无论错误如何,responseData 中都存在此“嵌套 JSON”。所以尝试在error 方法中使用我的代码,而不是success。如果您可以成功地将数据分配给变量authResult(JSON.parse 不会失败),那么我们只需从textStatuserrorThrown 中扣除到底出了什么问题。
【解决方案3】:

来自服务器的响应是 JSON 字符串格式。如果将 dataType 设置为 'json' jquery 将尝试直接使用它。您需要将 dataType 设置为“文本”,然后手动解析。

$.ajax({
    type: 'GET',
    dataType: "text", // You need to use dataType text else it will try to parse it.
    url: "http://someotherdomain.com/service.svc",
    success: function (responseData, textStatus, jqXHR) {
        console.log("in");
        var data = JSON.parse(responseData['AuthenticateUserResult']);
        console.log(data);
    },
    error: function (responseData, textStatus, errorThrown) {
        alert('POST failed.');
    }
});

【讨论】:

  • 仍然,我的脚本没有达到成功方法
【解决方案4】:

如果您打算使用JSONP,您可以使用为此而设计的getJSON。 jQuery 有JSONP 的辅助方法。

$.getJSON( 'http://someotherdomain.com/service.svc&callback=?', function( result ) {
       console.log(result);
});

阅读以下链接

http://api.jquery.com/jQuery.getJSON/

Basic example of using .ajax() with JSONP?

Basic how-to for cross domain jsonp

【讨论】:

    【解决方案5】:

    这是我的代码中的 sn-ps.. 如果它解决了你的问题..

    客户代码:

    设置 jsonpCallBack : 'photos' 和 dataType:'jsonp'

     $('document').ready(function() {
                var pm_url = 'http://localhost:8080/diztal/rest/login/test_cor?sessionKey=4324234';
                $.ajax({
                    crossDomain: true,
                    url: pm_url,
                    type: 'GET',
                    dataType: 'jsonp',
                    jsonpCallback: 'photos'
                });
            });
            function photos (data) {
                alert(data);
                $("#twitter_followers").html(data.responseCode);
            };
    

    服务器端代码(使用 Rest Easy)

    @Path("/test_cor")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String testCOR(@QueryParam("sessionKey") String sessionKey, @Context HttpServletRequest httpRequest) {
        ResponseJSON<LoginResponse> resp = new ResponseJSON<LoginResponse>();
        resp.setResponseCode(sessionKey);
        resp.setResponseText("Wrong Passcode");
        resp.setResponseTypeClass("Login");
        Gson gson = new Gson();
        return "photos("+gson.toJson(resp)+")"; // CHECK_THIS_LINE
    }
    

    【讨论】:

      【解决方案6】:

      您只需要像这样使用JSON.parse 解析字符串:

      var json_result = {"AuthenticateUserResult":"{\"PKPersonId\":1234,\"Salutation\":null,\"FirstName\":\"Miqdad\",\"LastName\":\"Kumar\",\"Designation\":null,\"Profile\":\"\",\"PhotoPath\":\"\/UploadFiles\/\"}"};
      
      var parsed = JSON.parse(json_result.AuthenticateUserResult);
      console.log(parsed);
      

      在这里你会有这样的东西:

      Designation
      null
      
      FirstName
      "Miqdad"
      
      LastName
      "Kumar"
      
      PKPersonId
      1234
      
      PhotoPath
      "/UploadFiles/"
      
      Profile
      ""
      
      Salutation
      null
      

      对于请求,不要忘记设置 dataType:'jsonp' 并在您网站的根目录中添加一个名为 crossdomain.xml 的文件,其中包含:

      <?xml version="1.0"?>
      <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
      <cross-domain-policy>
      <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
      
      <!-- Most restrictive policy: -->
      <site-control permitted-cross-domain-policies="none"/>
      
      <!-- Least restrictive policy: -->
      <!--
      <site-control permitted-cross-domain-policies="all"/>
      <allow-access-from domain="*" to-ports="*" secure="false"/>
      <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
      -->
      </cross-domain-policy>
      

      编辑以处理Sanjay Kumar POST

      因此您可以使用jsonpCallback 设置要在JSONP 中调用的回调函数!

      $.Ajax({
          jsonpCallback : 'your_function_name',
          //OR with anonymous function
          jsonpCallback : function(data) {
              //do stuff
          },
          ...
      });
      

      【讨论】:

      • 老兄,我的ajax成功方法没有触发
      • 是的,事实上你必须使用callback function,但在你的情况下,你不能,因为你没有另一手网站上的手!我再搜索一下……
      【解决方案7】:

      当使用“jsonp”时,您基本上会返回包装在函数调用中的数据,类似于

      jsonpCallback([{"id":1,"value":"testing"},{"id":2,"value":"test again"}])
      where the function/callback name is 'jsonpCallback'.
      

      如果您有权访问服务器,请先验证响应的"jsonp"格式是否正确

      对于来自服务器的此类响应,您还需要在 ajax 调用中指定一些内容,例如

      jsonpCallback: "jsonpCallback",  in your ajax call
      

      请注意,回调的名称不必是“jsonpCallback”,它只是作为示例选择的名称,但它需要与服务器端完成的名称(包装)匹配。

      我对您的问题的第一个猜测是服务器的响应不是应该的。

      【讨论】:

      • 我没有任何访问服务器的权限,我是否可以用我的 ajax 脚本做任何事情。
      • 如果您的回复只是 {"AuthenticateUserResult":"{\"PKPersonId\":1234,\"Salutation\":null,\"FirstName\":\"Miqdad\",\" LastName\":\"Kumar\",\"Designation\":null,\"Profile\":\"\",\"PhotoPath\":\"\/UploadFiles\/\"}"} 并且不是包裹在回调中,我认为您不能使用它。 “jsonp”只是在幕后利用脚本标签,没有“回调”,我认为您无法在代码中获取响应。
      • 我试过删除 jsonp。但是那个时候ajax错误方法正在触发并且也没有得到任何响应。
      • 您的主要问题是服务器没有以可以称为跨域(使用jsonp)的格式发送响应。您不能使用 json 作为其跨域。除非服务器的响应有与之关联的“回调”名称,否则我认为您在进行跨域调用时不能使用它
      • 我能想到的 3 种方法可以用来进行你想要的跨域调用。 JSONP,CORS 和使用代理在您的情况下,看起来“jsonp”无法使用,因为响应不是“jsonp”支持的格式(将响应包装在回调中)
      猜你喜欢
      • 2011-03-31
      • 2015-10-06
      • 2023-03-30
      • 2011-07-03
      • 2011-12-30
      • 2013-04-04
      • 2011-07-05
      • 2011-11-06
      相关资源
      最近更新 更多