调用Redmine API时jsonp得到404

Posted

技术标签:

【中文标题】调用Redmine API时jsonp得到404【英文标题】:jsonp getting 404 when calling Redmine API 【发布时间】:2016-03-22 21:35:26 【问题描述】:

我正在尝试使用 angularjs 项目中的 Redmine API。

我最终使用 jsonp 来解决 CORS 问题。

我在调用这个时收到 404:

var url = 'http://muser:mpasswd@myredmine/issues.json?callback=displayIssues';
 $http(
                method: 'JSONP',
                url: url
            ).
            success(function (data, status) 
                console.log("success");
                console.log(data);
            ).
            error(function (data, status) 
                console.log("Error: " + status);
            );
...
    function displayIssues(issues) 
                console.log('displayIssues');
                ...
            

但是当我用 Postman 调用相同的 url 时,它可以工作。

为什么我会收到这个 404?

这是我的控制台:

GET http://muser:mpasswd@myredmine/issues.json?callback=displayIssues jsonpReq @ angular.js:8576(anonymous function) @ angular.js:8420sendReq @ angular.js:8291serverRequest @ angular.js:8025wrappedCallback @ angular.js:11498wrappedCallback @ angular.js:11498(anonymous function) @ angular.js:11584Scope.$eval @ angular.js:12608Scope.$digest @ angular.js:12420Scope.$apply @ angular.js:12712(anonymous function) @ angular.js:18980x.event.dispatch @ jquery-2.0.3.min.js:5y.handle @ jquery-2.0.3.min.js:5
authentication.service.js:100 Error: 404

Rest API 和 jsonp 都在 admin->setting->auth 中启用

我也试过了:

        var url = 'http://muser:mpasswd@myredmine/redmine/issues.json&callback=JSON_CALLBACK';
        $http.jsonp(url, 
            params: 
                callback: 'JSON_CALLBACK',
                format: 'json'
            
        ).success(function (data) 
            console.log('ok');
        ).error(function (data) 
            console.log('error: ' + JSON.stringify(data));
        );

得到这个:

GET http://muser:mpasswd@myredmine/issues.json&callback=angular.callbacks._0?callback=JSON_CALLBACK&format=json jsonpReq @ angular.js:8576(anonymous function) @ angular.js:8420sendReq @ angular.js:8291serverRequest @ angular.js:8025wrappedCallback @ angular.js:11498wrappedCallback @ angular.js:11498(anonymous function) @ angular.js:11584Scope.$eval @ angular.js:12608Scope.$digest @ angular.js:12420Scope.$apply @ angular.js:12712(anonymous function) @ angular.js:18980x.event.dispatch @ jquery-2.0.3.min.js:5y.handle @ jquery-2.0.3.min.js:5
services.js:35 error: undefined

另外,当调用这个时:

var url = 'http://muser:mpasswd@myredmine/redmine/issues.json&callback=JSON_CALLBACK';
            $http.jsonp(url).success(function (data) 
                console.log('success');
            ).error(function (error) 
                console.log('error:: ' + error);
            );

我遇到同样的错误

请注意,muser、mpasswd 和 myredmine 只是示例。

【问题讨论】:

您是否通过 Postman 测试过 url?它对我不起作用。 我已经测试过了,但是我写的url(myredmine)只是一个例子 当你通过邮递员向这个url发送一个GET的结果是什么? 这是我帐户的所有问题。 displayIssues("issues":["id":1831,"project":"id":167,... 您有错误 404,请务必先在邮递员中删除它... 【参考方案1】:

来自ngDocs:

回调的名称应该是字符串 JSON_CALLBACK

Angular 将在内部用 angular.callbacks_0-9a-z 替换该字符串

所以先把你的代码改成这样:

var url = 'http://muser:mpasswd@myredmine/redmine/issues.json?callback=JSON_CALLBACK';
$http.jsonp(url).succe...

玩这个fiddle 似乎Redmine 会从网址中去除点.,从而使angular.callbacks_0 变为angularcallback_0,这是未定义的。 您可以在github 上阅读更多内容,这是一个问题。

可能的解决方案

1) 另一个用户在 SO here 上发布了一个 hack,将回调的名称更改为自定义名称。

根据@Todi-Adiatmo 的hack 工作fiddle。

2) 根据@dancras 在github 上发布的问题发现的另一个解决方案是通过调用angular.callbacks_.. 来定义未定义的angularcallbacks_..,然后删除全局angularcallbacks_ . 您必须在 jsonp 调用之前立即使用它:

var c = $window.angular.callbacks.counter.toString(36);

$window['angularcallbacks_' + c] = function (data) 
    $window.angular.callbacks['_' + c](data);
    delete $window['angularcallbacks_' + c];
;

根据@danca 的解决方案工作fiddle。

【讨论】:

我不明白,我应该使用一种变通方法来使其与 Redmine API 一起工作吗?如果是这样,当他们修复它时会发生什么? 根据 github Angular 团队的问题页面,不会改变这一点。我猜这取决于redmine团队。您始终可以正确设置 CORS 并使用 json 而不是 jsonp 我已经更新了我的答案。添加了链接以阅读有关此的更多信息。 redmine也有问题redmine.org/issues/13718#change-58154 如何使用 redmine 正确设置 CORS 并使用 json? 让我们continue this discussion in chat。【参考方案2】:

我看到你的控制台显示这个:-

获取http://muser:mpasswd@myredmine/issues.json?callback=displayIssues

从技术上讲,这不是 HTTP 中的有效 URL。用户名和密码不应该在 GET 调用中,它们应该在标题中,根据。

https://en.wikipedia.org/wiki/Basic_access_authentication

在谷歌上快速搜索发现这个https://docs.angularjs.org/api/ng/service/$http 和 angularjs basic authentication headers

我已经好几年没看过 redmine 了,它可能只需使用之前的答案指定的选项就可以很好地处理不可靠的 HTTP,但如果这不起作用,请检查请求是否真正正确地到达 Redmine

【讨论】:

以上是关于调用Redmine API时jsonp得到404的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSONP 和 JQuery 调用 REST Api

如何使用 jquery 对 api 进行 jsonp 调用

JSONP详解

使用 JQuery Ajax 和 JSONP 调用 OData 服务

Angular JSONP 调用 WordPress JSON REST API

封装jsonp