【问题标题】:Is it Possible to Make Cross-Domain Requests in Javascript AND Set Custom Headers?是否可以在 Javascript 中进行跨域请求并设置自定义标头?
【发布时间】:2011-03-05 15:20:21
【问题描述】:

Since you can't apply custom headers on JSONP calls,如何使用 jQuery 进行跨域请求并应用自定义标头?

我基本上是在尝试使用 jQuery 访问谷歌文档,并且需要传递一个身份验证令牌:

var token = "my-auth-token";
$.ajax({
  url: "http://docs.google.com/feeds/documents/private/full?max-results=1&alt=json",
  dataType: 'json',
  beforeSend: function(xhr) {
    xhr.setRequestHeader("Authorization", "GoogleLogin auth=" + token);
  },
  success: function(data, textStatus, XMLHttpRequest) {
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
  }
});

注意:这样做的目的是完全绕过应用层。使用 ruby​​ 连接到 Google Data API 很简单,但它一直在服务器端解析提要占用大量资源。

【问题讨论】:

  • 您不能这样做,原因与您不能向myBank.com 发出相同类型的请求一样,这会获取我的信息或锁定我的帐户,这两种方法都是非常不可取的。 ..以及为什么不允许这样的跨域请求。

标签: javascript jquery ajax cross-domain custom-headers


【解决方案1】:

您可以使用 Google 的 JavaScript 客户端库来查询 Docs API。尽管它没有专门为 Docs 提供帮助程序,但它仍然可以与大多数 API 一起使用,包括 Docs。请参阅 Google 员工的 blog post,其中显示了一个工作示例。

如果您最终陷入无限循环的授权,请参阅来自 Google 群组的 related question。基本上,cookie 的设置速度不够快,因此当 JavaScript 客户端库检查时,它什么也没找到并重定向到 OAuth 授权页面。一个解决方案是在检查完成之前添加一个小的延迟,或者使用一个登录按钮来启动授权,而不是在页面加载时进行。

您还需要将任何图像添加到位于同一域中的页面。可以用 CSS 隐藏,只要在 DOM 中即可。

使用上述博客文章中的示例,我能够仅使用 JavaScript 检索我的文档列表。这是我用来摆脱无限授权循环的修改后的初始化函数:

function initialize() {
    var scope = 'http://docs.google.com/feeds/';

    if (google.accounts.user.checkLogin(scope)) {
        var service = new google.gdata.client.GoogleService('writely', 'DocList-App-v1.0');   
        service.getFeed(scope + 'documents/private/full/', handleFeed, handleError);  
    } else {
        var loginButton = $("<button>Click here to login</button>");
        loginButton.click(function() {
            var token = google.accounts.user.login(scope); // can ignore returned token  
        });
        $("body").append(loginButton);
    }
};  
​

【讨论】:

  • 快到了!现在我在调用service.getFeed 时收到此错误:“未捕获的错误:此页面上需要相同域的图像才能进行经过身份验证的读取和所有写入。”有什么想法???
  • @viatropos - 你快到了。将任何图像放在页面上,但它必须位于同一域中。例如,我将这个临时图像放在页面上并用样式表隐藏它 - &lt;img src="/images/a.png" style="display: hidden" /&gt;
  • 太棒了!这正是我想要的,非常感谢 Anurag。
【解决方案2】:

考虑在服务器端编写一些用于代理的代码并让 jQuery 调用它。

【讨论】:

  • 你可以。许多较新版本的浏览器(包括 IE8)都支持跨域 XHR。
  • @Eli - 不,你不能,不是 OP 最初的方式......这不是“支持它”的问题,恰恰相反,他们是 积极的防止它,作为一种安全措施。
  • @Eli:我更新了答案以删除“你不能”。如果您更正否决票,我们将不胜感激。
  • 已修复。 @Nick:我只是用一些可行的方法来回答提问者的问题,如果他能让谷歌支持的话。
【解决方案3】:

您可以,只要外部域通过发送适当的Access-Control-Allow-Origin 标头允许它。然后在支持标准跨域 XHR API 的浏览器中使用XMLHttpRequest API,在 IE 中使用XDomainRequest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 2012-12-05
    • 2016-02-21
    • 2011-07-03
    • 2014-11-22
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多