【问题标题】:Using Ajax, how do you fire and forget across domains使用 Ajax,如何跨域触发和遗忘
【发布时间】:2012-10-12 17:08:15
【问题描述】:

我想对 Web 服务进行一次即发即弃的 jQuery 调用。

基本上,我想向http://myservice.com/uservisits/create 发送一个 JSON 对象,并且我不在乎接收任何类型的返回响应。但是,我们希望为多个域使用相同的服务,这意味着要面对与 Ajax 相关的跨域限制。

你是怎么做到的? JSONP 之类的有很多,但我不需要处理响应。我觉得我错过了一个明显的细节。

【问题讨论】:

  • 不是重复的。提供的链接说“我需要在之后获取并解析响应。”我不需要解析请求。
  • 对,但你可以这样做,只是不解析响应......
  • @gilly3:关闭问题不会神奇地将其从搜索结果中删除。此外,我从未说过这是一个不好的 问题或应该删除,我只是指出我认为这是一个先前提出的问题的重复。这个问题仍然是“周围”和可定位的,它肯定仍然有利于社区。我会将其归类在您发布的链接的 #2 下。
  • StackOverflow 的一个不幸方面是它强化了我们职业的一个方面,即欺负那些行业经验/知识/教育/SO 声誉点较低的人。我,问题作者(也就是需要帮助的人)承认另一个问题很有价值,但不相信它完全回答了我的问题。我与@Adam 的交流表明了我的意思,我从他对我的问题的后续澄清中获得了价值。也许您认为我应该能够从另一个问题中找出答案,但这真的是您的决定吗?
  • 关闭一个不完全重复的问题的不幸之处在于,不可能添加一个不适用于其他问题的特定于该问题的新答案。

标签: jquery ajax cross-domain


【解决方案1】:

发送 http GET 请求的最简单方法是使用图像信标:

var json = encodeURIComponent(JSON.stringify(obj));
new Image().src = "http://myservice.com/uservisits/create?JSON=" + json;

而且,您甚至可以通过处理loaderror 事件来获取一些信息。当然,如果响应不是图像,则将调用error 事件,而不是load。您可以将服务设置为返回单像素图像来解决这个问题。

编辑:mentioned 您可能更喜欢使用 HTTP POST。它不像图像信标那么简单,但您可以使用隐藏的 iframe 进行跨域发布:

var frame = $("<iframe>").hide();
frame.load(function() {
    var frameBody = frame.contents().find("body");
    var form = $("<form>", {
        action: "http://myservice.com/uservisits/create",
        method: "POST"
    });
    form.appendTo(frameBody);
    $("<input/>", {
        name: "json",
        value: json
    }).appendTo(form);
    form[0].submit();
});
frame.appendTo("body");

认为 jQuery 已经内置了类似的东西。您可以尝试深入了解jQuery.ajax 文档。如果没有,您可能会找到一个可以做到这一点的插件。

【讨论】:

  • 虽然这可能是处理事情的好方法,但无法处理错误情况,因为 OP 似乎并不关心可能没问题的响应。或者,您可以在图像对象上设置“onError”处理程序,但无法将实际错误数据传回调用类,只能以这种方式处理一般错误。
  • @FilmJ - 当然。但是,这个问题是关于您不打算解析响应的特定情况。图像信标方法非常适合这种情况。
  • @FilmJ - 此外,您可以在错误处理方面非常有创意。 1px x 1px 的图像可能表示成功。任何其他图像大小都可能指示错误代码,可按大小破译。或者,甚至可能在生成的图像中显示错误消息。
  • 所有给出的答案都有效并受到赞赏。从长远来看,我认为 CORS 是答案,但我今天还没准备好这样做。我将其标记为“答案”,因为它提供了一个巧妙的技巧(浏览器对图像的支持与时间一样古老)和一个 iFrame 解决方案,如果被调用的服务是 RESTful,它将起作用。
【解决方案2】:

您没有处理响应这一事实不会影响您面临的同一来源策略问题。但是,您将控制服务的所有消费者这一事实开启了使用CORS 的可能性。但是,并非所有浏览器都支持 CORS。 See the browser compatibility chart.如果需要支持其他浏览器还是要使用JSONP。

【讨论】:

  • “使用 JSONP”是指 dataType: "JSONP" 吗?如果没有回调,“使用 JSONP”是什么意思?
  • @John 表示使用脚本元素注入。基本上,您需要做的就是在页面上创建一个脚本元素,并将您要点击的 URL 作为源。您的服务需要 POST 还是 GET 请求?
  • 我可以构建服务来获取其中任何一个,尽管 POST 更准确地识别出正在执行的操作,而不是检索。
  • GET 会更容易。那么你所要做的就是使用dataType jsonp。
  • 所以我只使用 $.get( ... dataType: "JSONP" ...) 并且不包含回调,它会工作吗?是这样吗?
【解决方案3】:

您不希望任何数据返回的事实实际上是无关紧要的,您仍然面临相同的跨域问题。有两种方法可以走...

1) 您可以使用 jsonp(它实际上发出一个 get 请求)来发送数据,尽管这感觉有点混乱,因为您应该尝试使用 http 动词来表达他们的意图(即 GET 应该检索数据)。

2)您可以使用ARR(IIS中的应用程序请求路由)来基本上重写请求。因此,您将为每个域设置一个规则以具有重写规则,例如www.mydomain.com/webcall 路由到http://myservice.com/uservisits/create,其中 mydomain.com 是启动 ajax 调用的域。如果你这样做,那么你可以以正常方式使用 ajax,因为就浏览器而言,你现在在同一个域上发出请求

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2019-03-09
    • 2012-01-02
    • 1970-01-01
    • 2013-03-18
    • 2013-03-02
    相关资源
    最近更新 更多