【问题标题】:Angularjs $resource url intercept url encodingAngularjs $resource url 拦截 url 编码
【发布时间】:2015-12-29 14:35:38
【问题描述】:

我正在开发一种连接到 RESTFUL 文件 api 的文件管理器应用程序。 在 Angular 应用上,每个文件和目录都是 Angular $resource 的一个实例,使用文件对象属性 relativePathName 作为资源 id。

js var File = $resource(url + '/:type/:id', {id: '@relativePathName', type: '@type'}, {…});

问题是,在更新文件资源时,relativePathName 参数会被 url 编码,例如/ 变为 %2F 导致服务器在请求到达实际 API 之前拦截请求(我假设服务器将此视为物理地址并返回 404 响应)。 API 能够将整个 url 段视为单个参数,因此基本上它将 path/to/file 视为 http://myapp.com/api/files/create/path/to/file 的 uri 参数,而不是不同的 uri。

我的问题是,有没有办法在资源构造函数中的private Router instance 生成请求 url 后修改它?如果是这样,如何(在文档中对此一无所获)?什么是可能的解决方案?将 relativePathName 作为参数传递,而不是将其声明为资源 id(这需要修改 API)?

提前致谢。

托马斯

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    使用 $resource 并不是 RESTful 服务调用的一站式服务,它只是一种以某种方式构建的 api 的便利服务。如果 $resource 无法满足您的需求,只需使用适合您尝试调用的 api 的 $resource 和 $http 组合创建您自己的服务。

    【讨论】:

    • 谢谢,这可能是唯一的方法。经过一番修改后,我最终扩展了$resource() 检索到的构造函数并覆盖了$get,因为在我的情况下,这是唯一对编码的 url 参数至关重要的方法。
    【解决方案2】:

    在我们的应用中,我们希望 getByName 请求使用不同的 URL,因此我们使用操作 getByName 的 URL 参数覆盖资源地址,如下所示:

    myapp.factory('ListGroup', ['$resource',
         function($resource) {
    
            return $resource(
                '/API/List/:Id',
                {
                    Id:'@Id',
                    Name:'@Name'
                },
                {
                    getByName: {method: 'GET', url: '/API/List/Group/:Name', isArray: true}
                }
            );
    }
    

    ]);

    【讨论】:

      【解决方案3】:

      我的问题是,有没有办法在资源构造函数内部的私有路由器实例生成请求 url 后修改它?

      我不确定资源构造函数的内部,但您可以使用interceptors 在 $resource 生成路由 url 后以编程方式更改它们。

      结构

      hooks.config.js
      hooks.factory.js
      hooks.module.js
      

      hooks.module.js

      module.exports = angular
                          .module("app.hooks", [])
                          .factory("hooks", require("./hooks.factory.js"))
                          .config(require("./hooks.config.js"));
      

      hooks.config.js

      module.exports = ["$httpProvider", function($httpProvider) {
          $httpProvider.interceptors.push("hooks");
      }];
      

      hooks.factory.js

      module.exports = ["$q", "$location", function($q, $location) {
      
          var basePrefix = "/api/v1";
      
          return {
              //invoked on every http request
              request: function(request) {
                  request.url = interpret(request.url);
                  return $q.when(request);
              }
          };
      
          function interpret(str) {
              //if requesting an html template, don't do anything
              if (str.indexOf(".html") > -1)
                  return str;
              //if you're accessing the api, append the base prefix globally here
              else
                  return basePrefix + str;
          }
      }];
      

      【讨论】:

        猜你喜欢
        • 2014-06-07
        • 2014-06-30
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 2021-12-22
        • 2011-07-11
        • 1970-01-01
        相关资源
        最近更新 更多