Angularjs 将图像作为服务加载

Angularjs 将图像作为服务加载,angularjs,Angularjs,我有一个从API中提取对象的服务。某些对象可能包含图像URL。后端当前通过get_file_contents()扫描并处理这些内容,并将其转换为内联数据。这将严重影响我的服务器的吞吐量。我之所以这样做是因为我想缓存图像以便以后脱机,但在某种程度上,我仍然可以使用常规角度渲染对象 我无法使用$http.get()在浏览器中使用Javascript进行处理,因为承载图像的站点正在阻止跨站点请求。然后,我想做的是在浏览器中创建一个元素,该元素在加载服务后调用该服务,以便提取数据并使用它处理对象 我无法

我有一个从API中提取对象的服务。某些对象可能包含图像URL。后端当前通过get_file_contents()扫描并处理这些内容,并将其转换为内联数据。这将严重影响我的服务器的吞吐量。我之所以这样做是因为我想缓存图像以便以后脱机,但在某种程度上,我仍然可以使用常规角度渲染对象

我无法使用
$http.get()
在浏览器中使用Javascript进行处理,因为承载图像的站点正在阻止跨站点请求。然后,我想做的是在浏览器中创建一个
元素,该元素在加载服务后调用该服务,以便提取数据并使用它处理对象

我无法控制服务人员在应用程序内部存储get,并且在下载API对象之前,应用程序在任何时候都不知道URL

我也曾考虑过重新设置服务人员来存储我网站上的数据,但这似乎有点错误,而且我不确定它到底能工作得多好,另外,在开发过程中,我关闭了服务人员,因为这意味着我必须让整个网站加载两次才能完全刷新


有人能帮我通过浏览器将图像数据输入我的服务吗?

如果我一开始就找到了支持CORS的图像主机,我可能不需要它,可能只是使用了
$http
调用

需要指令、服务和控制器,以及支持CORS的主机(例如)。我也用过

以下是javascript代码:

// Using this from https://stackoverflow.com/questions/934012/get-image-data-in-javascript
function getBase64Image(img) {
    // Create an empty canvas element
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    // Copy the image contents to the canvas
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    // Get the data-URL formatted image
    // Firefox supports PNG and JPEG. You could check img.src to
    // guess the original format, but be aware the using "image/jpg"
    // will re-encode the image.
    var dataURL = canvas.toDataURL("image/png");

    return dataURL;
    //  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

// Used on the img tag to handle the DOM notification feeding into the service
app.directive('notifyimgsvc', function() {
    return {restrict : 'A', link : function(scope, element, attrs) {
        element.bind('load', function() {
            console.log('imgSvc::notify() image is loaded');
            console.log("imgSvc::notify(): " + this.src);
            imgSvc.notifyLoad(this.src, getBase64Image(this));

        });
        element.bind('error', function() {
            console.log('imgSvc::notify() image could not be loaded');
            console.log("imgSvc::notify(): " + this.src);
        });
    }};
});

// A core service to handle the comms in both directions from requests to data
app.service('imgSvc', [function(netSvc) {
    imgSvc = this; // to avoid ambiguoity in some inner function calls

    imgSvc.images = {}; // a cache of images
    imgSvc.requests = []; // the requests and their callbacks
    imgSvc.handlers = []; // handlers that will render images

    console.log("imgSvc::init()");

    // Allows a controller to be notified of a request for an image and
    // a callback to call when an image is added. There should only ever
    // be one of these so an array is probaby not needed and any further
    // requests should probably throw an error.
    imgSvc.registerHandler = function(callback) {
        console.log("imgSvc::registerHandler()");
        if (imgSvc.requests.length) {
            // Already have image requests, so tell the new handler about them
            for ( var i in imgSvc.requests) {
                callback(imgSvc.requests[i].url);
            }
        }
        // Add the new handler to the stack
        imgSvc.handlers.push(callback);
    };

    // The usage function from your code, provide a callback to get notified
    // of the data when it loads.
    imgSvc.getImg = function(url, callback) {
        console.log("imgSvc::getImg('" + url + "')");

        // If we have pre-cached it, send it back immediately.
        if (imgSvc.images[url] != undefined) {
            console.log("imgSvc::getImg('" + url + "'): Already have data for this one");
            callback(url, imgSvc.images[url]);
            return;
        }

        // push an object into the request queue so we can process returned data later.
        // Doing it this way als means you can have multiple requests before any data
        // is returned and they all get notified easily just by looping through the array.
        var obj = {"url" : url, "callback" : callback};
        if (imgSvc.handlers.length) {
            console.log("imgSvc::getImg('" + url + "'): informing handler");
            for ( var i in imgSvc.handlers) {
                imgSvc.handlers[i](obj.url);
            }
        }
        imgSvc.requests.push(obj);
    };

    // Notification of a successful load (or fail if src == null).
    imgSvc.notifyLoad = function(url, src) {
        console.log("imgSvc.notifyLoad()");
        // Save the data to the cache so any further calls can be handled
        // immediately without a request being created.
        imgSvc.images[url] = src;

        // Go though the requests list and call any callbacks that are registered.
        if (imgSvc.requests.length) {
            console.log("imgSvc.notifyLoadCallback('" + url + "'): scanning requests");
            for (var i = 0; i < imgSvc.requests.length; i++) {
                if (imgSvc.requests[i].url == url) {
                    console.log("imgSvc.notifyLoadCallback('" + url + "'): found request");
                    // found the request so remove it from the request list and call it
                    var req = imgSvc.requests.splice(i, 1)[0];
                    i = i - 1;
                    console.log("imgSvc.notifyLoadCallback('" + url + "')");
                    req.callback(url, src);
                } else {
                    console.log("imgSvc.notifyLoadCallback('" + url + "'): skipping request for '" + imgSvc.requests[i].url + "'");
                }
            }
        } else {
            console.log("imgSvc.notifyLoadCallback('" + url + "'): No requests present??");
        }
    };

    // The notifiy fail is just a logging wrapper around the failure.
    imgSvc.notifyFail = function(url) {
        console.log("imgSvc.notifyFail()");
        imgSvc.notifyLoad(url, null);
    };
}]);

// A simple controller to handle the browser loading of images.
// Could probably generate the HTML, but just doing simply here.
app.controller('ImageSvcCtrl', ["$scope", function($scope) {
    $scope.images = [];
    console.log("imgSvcCtrl::init()");

    // Register this handler so as images are pushed to the service,
    // this controller can render them using regular angular.
    imgSvc.registerHandler(function(url) {
        console.log("imgSvcCtrl::addUrlHandler('" + url + "')");
        // Only add it if we don't hqve it already. The caching in the
        // service will handle multiple request for the same URL, and
        // all associated malarkey
        if ($scope.images.indexOf(url) == -1) {
            $scope.images.push(url);
        }
    });

}]);

为什么匿名否决票(
<div data-ng-controller="ImageSvcCtrl" style="display:none;">
    <img data-ng-repeat="img in images" data-ng-src="{{img}}" alt="loading image" crossorigin="anonymous" notifyimgsvc />
</div>
var req_url = "https://i.imgur.com/lsRhmIp.jpg";
imgSvc.getImg(req_url, function(url, data) {
    if(data) {
        logger("MyCtrl.notify('" + url + "')");
    } else {
        logger("MyCtrl.notifyFailed('" + url + "')");
    }
});