JSONP 请求跨域工作,但无法确定来源

Posted

技术标签:

【中文标题】JSONP 请求跨域工作,但无法确定来源【英文标题】:JSONP request working cross-domain, but can't figure out origin 【发布时间】:2012-11-13 06:58:40 【问题描述】:

我正在尝试 JSONP 调用。我在服务器 1 中有一个 NodeJs 应用程序,位于 domain1.com 域下,如下所示:

server.get('/api/testjsonp', function(req, res) 

  var clientId = req.param('clientId');

  res.header('Content-Type', 'application/json');
  res.header('Charset', 'utf-8') 
  res.send(req.query.callback + '("something": "rather", "more": "fun",
          "sourceDomain": "' + req.headers.origin + '"' + ',"clientId":"' + clientId + 
          '");');  

);

在另一台服务器(服务器 2)和不同的域(domain2.com)下,我创建了一个测试 html 页面,调用如下:

    var data =  clientId : 1234567890 ;

            $.ajax(
                    dataType: 'jsonp',
                    data: data,
                    jsonp: 'callback',
                    url: 'https://domain1.com/api/testjsonp?callback=1',                        
                    success: function(data) 
                        alert('success');
                    ,
        error: function(err)
                        alert('ERROR');
                        console.log(err);
                    
                );

我这里有两个问题:

1) 为什么会这样?这不是一个跨域调用,因此我需要实现 ALLOW-ORIGIN 标头的东西吗?我正在关注这个例子:

http://css.dzone.com/articles/ajax-requests-other-domains

http://benbuckman.net/tech/12/04/cracking-cross-domainallow-origin-nut

2) 在服务器中,我不知道是哪个域在进行调用,req.headers.origin 始终未定义。我希望能够知道正在调用哪个域,以防止不必要的调用。替代方案我可以检查呼叫 IP,知道如何吗?

非常感谢

【问题讨论】:

【参考方案1】:

为什么会这样?这不是一个跨域调用,因此我需要实现 ALLOW-ORIGIN 标头的东西吗?我

就浏览器而言,您并不是直接从不同来源读取数据。您正在从另一个来源加载一个 javascript 程序(它恰好捆绑了一些数据)。

在服务器中,我无法确定是哪个域进行了调用,req.headers.origin 始终未定义。我希望能够知道调用的是哪个域,以防止不必要的调用。

引用页面的 URL 存储在 Referer 标头中,而不是 Origin 标头中。但是,它是可选的,在很多情况下都不会发送。

如果您想限制对某些网站的数据访问,则不能使用 JSON-P。请改用纯 JSON 和 CORS。

或者,我可以检查呼叫 IP,知道怎么做吗?

这将为您提供客户端的地址,而不是将客户端指向您的服务器。

【讨论】:

非常感谢您的及时回复。如果我理解正确,它可以正常工作(即此处不需要 ALLOW-ORIGIN 标头)。在这种特殊情况下,知道调用的是哪个域对我来说很重要。调用者域(由我控制)是否可以执行任何操作以始终填充Referer 标头? 服务器端,我在看req.headers.origin。如果提供,我假设客户端正在使用 CORS。否则,我会查看 req.headers.referer 并假设客户端正在使用 JSONP。然后,我将此值与我的授权域列表进行比较。如果授权,则进行否则发送错误。这是确保只有授权域请求此服务的正确方法吗?谢谢

以上是关于JSONP 请求跨域工作,但无法确定来源的主要内容,如果未能解决你的问题,请参考以下文章

发出跨域请求时无法使用 JSONP 取回任何数据

对 JSONP 请求的工作方式感到困惑

解决跨域的方式(9种)

跨域JSONP原理及调用详细演示样例

jsonp跨域请求的方式

Jsonp跨域请求