AngularJS / PouchDB应用程序停止同步到CouchDB的时候cache.manifest添加 [英] AngularJS/PouchDB app stops syncing to CouchDB when cache.manifest added

查看:93
本文介绍了AngularJS / PouchDB应用程序停止同步到CouchDB的时候cache.manifest添加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用AngularJS编写一个页面的Web应用程序。它采用PouchDB复制到CouchDB的服务器和正常工作。

问题是当我尝试通过增加cache.manifest将网页转换为可脱机使用。突然所有的复制任务抛出错误而停止工作,无论是工作脱机或联机。

在Chrome浏览器,它只是说:GET ... myCouchIP / MYDB /?_随机数= CxVFIwnEJeGFcyoJ网:: ERR_FAILED

在Firefox中它也抛出一个错误,但提到的请求被阻止 - 尝试启用CORS

CORS在远程CouchDB的启用按从PouchDB设置页面中的说明。加上它而不是使用cache.manifest工作正常(即它是很高兴我的办公桌之间的服务器和虚拟机的所有不同的IP地址, - 这是一个原型所以有此时没有域名)。

顺便说一下,在这个时候,我没有使用任何种类的认证。管理方生效。

那么,加入cache.manifest时变化?线索感激的欢迎。
先谢谢了。

app.js

  VAR应用= angular.module('资产',['assets.controllers','ngRoute']);的app.config(['$ routeProvider',函数($ routeProvider){
    $ routeProvider。
    什么时候('/', {
        控制器:'OverviewCtrl',
        templateUrl:意见/ overview.html
    })。
    当('/新',{
        控制器:'NewMachineCtrl',
        templateUrl:意见/ machineForm.html
    })。
    否则({redirectTo:'/'});
}]);

controller.js

  VAR _control = angular.module('assets.controllers',['assets.services']);_control.controller('OverviewCtrl',['$范围','机',函数($范围,机){
    VAR承诺= Machine.getAll();    promise.then(功能(machineList){
        $ scope.machines = machineList;
    },函数(原因){
        警报('机列表为空:'+原因);
    });
}]);_control.controller('UpdateMachineCtrl',['$范围,$ routeParams','机',
                                            功能($范围,$ routeParams,机){
    $ scope.title =更新安装详细信息;
    VAR承诺= Machine.getSingle($ routeParams.docId);    promise.then(功能(机){
        $ scope.machine =机;
    },函数(原因){
        警报('记录无法检索');
    });    $ scope.save =功能(){
        Machine.update($ scope.machine);
    };
}]);_control.controller('SyncCtrl',['$范围','机',函数($范围,机){
    $ scope.syncDb =功能(){
        Machine.sync();
        Machine.checkConflicts();
    };    $ scope.checkCors =功能(){
        //检查CORS支持
        VAR corsCheck =功能(方法,URL){
          VAR XHR =新XMLHtt prequest();          如果(在XHRwithCredentials){
            // XHR为Chrome /火狐/歌剧/ Safari浏览器。
            xhr.open(方法,URL,真正的);
          }否则如果(typeof运算XDomainRequest!=未定义){
            // XDomainRequest的IE浏览器。
            XHR =新XDomainRequest();
            xhr.open(方法,URL);
          }其他{
            //不支持CORS。
            的console.log('CORS不是浏览器支持');
          }          xhr.onload =功能(){
              的console.log('从CORS响应'+方法+'请求'+ URL +:+ xhr.responseText);
          };
          xhr.onerror =功能(){
              的console.log('错误的CORS响应'+方法+'请求'+ URL +:+ xhr.responseText);
          };          xhr.send();
        };        VAR服务器='http://10.100.3.21:5984/ass_support';        corsCheck('GET',服务器);
        corsCheck('把',服务器);
        corsCheck('POST',服务器);
        corsCheck(HEAD,服务器);
// corsCheck('删除',服务器);
    };
}]);

service.js

  VAR _service = angular.module('assets.services',[]);_service.constant('DBCONFIG',{
    DBNAME:'资产',
    DBSERVER:HTTP:// myCouchServerIp:5984 /'
});/ **
 *请在PouchDB提供AngularJS。
 * /
_service.factory('$ DB',['DBCONFIG',函数(DBCONFIG){
    PouchDB.enableAllDbs = TRUE;
    VAR的LocalDB =新PouchDB(dbConfig.dbName);
    VAR remoteDb = dbConfig.dbServer + dbConfig.dbName;
    VAR的选择= {直播:真正};
    VAR syncError =功能(){
        的console.log('数据库同步过程中遇到的问题);
    };    的console.log('从本地到服务器进行复制');
    localDb.replicate.to(remoteDb,期权,syncError);    的console.log('从服务器复制回本地');
    localDb.replicate.from(remoteDb,期权,syncError);    返回的LocalDB;
}]);_service.factory('机',['$ Q,$ DB','$ rootScope','DBCONFIG',
                   功能($ Q $分贝,$ rootScope,DBCONFIG){
    返回{
        更新:功能(机){
            VAR延迟= $ q.defer();            VAR DOC = {
               _id:machine._id,
               _rev:machine._rev,
               类型:machine.type,
               顾客:machine.customer,
               工厂:machine.factory,
               另一LineID:machine.lineId,
               plcVersion:machine.plcVersion,
               dateCreated会:machine.dateCreated,
               LASTUPDATED:新的Date()toUTCString()
            };            $ db.put(文件,功能(错误响应){
                $ rootScope。$应用(函数(){
                    如果(错误){
                        的console.log('更新失败:');
                        的console.log(错误);
                        delay.reject(错误);
                    }其他{
                        的console.log('更新成功:');
                        的console.log(响应);
                        delay.resolve(响应);
                    }
                });
            });            返回delay.promise;
        },
        GETALL:功能(){
            VAR延迟= $ q.defer();            VAR地图=功能(DOC){
                如果(doc.type ==='机'){
                    发射([doc.customer,doc.factory]
                            {
                                _id:doc._id,
                                顾客:doc.customer,
                                工厂:doc.factory,
                                另一LineID:doc.lineId,
                                plcVersion:doc.plcVersion,
                            }
                    );
                }
            };            $ db.query({地图:地图},功能(错误响应){
                $ rootScope。$应用(函数(){
                    如果(错误){
                        delay.reject(错误);
                    }其他{
                        的console.log('查询检索'+ response.rows.length +行);
                        变种queryResults = [];                        //创建从响应的阵列
                        response.rows.forEach(函数(行){
                            queryResults.push(row.value);
                        });                        delay.resolve(queryResults);
                    }
                });
            });            返回delay.promise;
        },
        同步:功能(){
            VAR remoteDb = dbConfig.dbServer + dbConfig.dbName;
            VAR的选择= {直播:真正};
            VAR syncError =功能(错误,变更){
                的console.log('数据库同步过程中遇到的问题);
                的console.log(错误);
                的console.log(变化);
            };
            VAR syncSuccess =功能(错误,变更){
                的console.log(同步成功);
                的console.log(错误);
                的console.log(变化);
            };            的console.log('从本地到服务器进行复制');
            $ db.replicate.to(remoteDb,期权,syncError)。
                在('错误',syncError)。
                在('完成',syncSuccess);            的console.log('从服务器复制回本地');
            $ db.replicate.from(remoteDb,期权,syncError);
        }
    };
}]);_service.factory('dbListener',['$ rootScope,$ DB',函数($ rootScope,$ DB){
    的console.log('注册的onChange听众');
    $ db.info(功能(错误响应){
        $ db.changes({
            因为:response.update_seq,
            住:真实,
        })。在('变化',函数(){
            的console.log('由dbListener检测到的变化');
            // TODO明白为什么这永远不会发生
        });
    });
}]);

cache.manifest

  CACHE MANIFEST#看法
意见/ machineForm.html
意见/ overview.html#脚本
脚本/供应商/ pouchdb-2.2.0.min.js
脚本/供应商/角1.2.16.min.js
脚本/供应商/角路由1.2.16.min.js脚本/ app.js
脚本/控制器/ controller.js
脚本/服务/ service.js

的index.html

 <!DOCTYPE HTML>
< HTML LANG =EN清单=cache.manifest数据-NG-应用=资产>
< HEAD>
<间的charset =UTF-8>
< META NAME =视口CONTENT =WIDTH =设备宽度,初始规模= 1>
<标题>资产管理及LT; /标题><脚本SRC =脚本/供应商/角1.2.16.min.js类型=文/ JavaScript的>< / SCRIPT>
<脚本SRC =脚本/供应商/角路由1.2.16.min.js类型=文/ JavaScript的>< / SCRIPT>
<脚本SRC =脚本/供应商/ pouchdb-2.2.0.min.js类型=文/ JavaScript的>< / SCRIPT><脚本SRC =脚本/ app.js类型=文/ JavaScript的>< / SCRIPT>
<脚本SRC =脚本/服务/ service.js类型=文/ JavaScript的>< / SCRIPT>
<脚本SRC =脚本/控制器/ controller.js类型=文/ JavaScript的>< / SCRIPT>
< /头>
<身体GT;
    < D​​IV ID =内容>
    <导航类=侧边栏>
    < H3>选项< / H3 GT&;
    < D​​IV>
        &所述;类别=有效的数据纳克-的href =#/>概要&下; / A>
        &下;一个数据纳克-的href =#的数据纳克控制器=SyncCtrl数据纳克点击=syncDb()>调校&下; / A>
        &下;一个数据纳克-HREF =数据纳克控制器=SyncCtrl数据纳克点击=checkCors()>检查CORS&下; / A>
    < / DIV>
    < / NAV>    <节类=主>
        < D​​IV数据-NG-视图>< / DIV>
    < /节>
    < / DIV>
< /身体GT;
< / HTML>

overview.html

 < H3>安装概述< / H3 GT&;
<表>
    &所述; TR>
        <第i个客户和LT; /第i
        <第i个工厂和LT; /第i
        <第i行ID< /第i
        <第i PLC版本< /第i
    < / TR>
    < TR数据-NG-重复=机机>
        &所述; TD> {{machine.customer}}&下; / TD>
        &所述; TD> {{machine.factory}}&下; / TD>
        &所述; TD>&下;一个数据纳克-的href =#/视图/ {{machine._id}}> {{machine.lineId}}&下; / A>&下; / TD>
        &所述; TD> {{machine.plcVersion}}&下; / TD>
    < / TR>
< /表>

machineForm.html

 < H3>的{{title}}< / H3 GT&;
<表格名称=machineForm数据-NG-提交=保存()>
    < D​​IV>
    <标签=客户>客户:LT; /标签>
< D​​IV><输入数据-NG-模式=machine.customerID =客户要求>< / DIV>
    < / DIV>    < D​​IV>
    <标签=工厂>工厂:其中; /标签>
    < D​​IV><输入数据-NG-模式=machine.factoryID =工厂需要与GT;< / DIV>
    < / DIV>    < D​​IV>
<标签=另一LineID>线路编号:LT; /标签>
    < D​​IV><输入数据-NG-模式=machine.lineIdID =另一LineID要求>< / DIV>
    < / DIV>    < D​​IV>
<标签=plcVersion> PLC版本:其中; /标签>
    < D​​IV><输入数据-NG-模式=machine.plcVersionID =plcVersion>< / DIV>
    < / DIV>    < D​​IV><按键数据-NG-禁用=$ machineForm无效。>保存< /按钮>< / DIV>
< /表及GT;


解决方案

试着改变你的cache.manifest文件,以这样的:

  CACHE MANIFESTCACHE:
#看法
意见/ machineForm.html
意见/ overview.html#脚本
脚本/供应商/ pouchdb-2.2.0.min.js
脚本/供应商/角1.2.16.min.js
脚本/供应商/角路由1.2.16.min.js脚本/ app.js
脚本/控制器/ controller.js
脚本/服务/ service.js网络:
*

当使用一个manifest文件,所有的非缓存资源将无法缓存的网页上,甚至当你在线。网络部分告诉浏览器,允许请求非缓存的资源(他们将仍然无法在离线状态下,当然)。

I have a single page web app written using AngularJS. It uses PouchDB to replicate to a CouchDB server and works fine.

The problem comes when I try to convert the webpage to be available offline by adding cache.manifest. Suddenly ALL the replication tasks throw errors and stop working, whether working offline or online.

In Chrome it just says "GET ...myCouchIP/myDB/?_nonce=CxVFIwnEJeGFcyoJ net::ERR_FAILED"

In Firefox it also throws an error but mentions that the request is blocked - try enabling CORS.

CORS is enabled on the remote CouchDB as per the instructions from PouchDB setup page. Plus it works fine while not using the cache.manifest (i.e. it is quite happy with all the different ip addresses between my desk, the server and a VM - it is a prototype so there are no domain names at this time).

Incidentally, at this time I am not using any kind of authentication. Admin party is in effect.

So what changes when adding the cache.manifest? Clues gratefully welcomed. Thanks in advance.

app.js

var app = angular.module('Assets', ['assets.controllers', 'ngRoute']);

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
    when('/', {
        controller: 'OverviewCtrl',
        templateUrl: 'views/overview.html'
    }).
    when('/new', {
        controller: 'NewMachineCtrl',
        templateUrl: 'views/machineForm.html'
    }).
    otherwise({redirectTo: '/'});
}]);

controller.js

var _control = angular.module('assets.controllers', ['assets.services']);

_control.controller('OverviewCtrl', ['$scope', 'Machine', function($scope, Machine) {
    var promise = Machine.getAll();

    promise.then(function(machineList) {
        $scope.machines = machineList;
    }, function(reason) {
        alert('Machine list is empty: ' + reason);
    });
}]);

_control.controller('UpdateMachineCtrl', ['$scope', '$routeParams', 'Machine', 
                                            function($scope, $routeParams, Machine) {
    $scope.title = "Update Installation Details";
    var promise = Machine.getSingle($routeParams.docId);

    promise.then(function(machine) {
        $scope.machine = machine;
    }, function(reason) {
        alert('Record could not be retrieved');
    });

    $scope.save = function() {
        Machine.update($scope.machine);
    };
}]);

_control.controller('SyncCtrl', ['$scope', 'Machine', function($scope, Machine) {
    $scope.syncDb = function() {
        Machine.sync();
        Machine.checkConflicts();
    };

    $scope.checkCors = function() {
        // Check CORS is supported
        var corsCheck = function(method, url) {
          var xhr = new XMLHttpRequest();

          if ("withCredentials" in xhr) {
            // XHR for Chrome/Firefox/Opera/Safari.
            xhr.open(method, url, true);
          } else if (typeof XDomainRequest != "undefined") {
            // XDomainRequest for IE.
            xhr = new XDomainRequest();
            xhr.open(method, url);
          } else {
            // CORS not supported.
            console.log('CORS not supported by browser');
          }

          xhr.onload = function() {
              console.log('Response from CORS ' + method + ' request to ' + url + ': ' + xhr.responseText);
          };
          xhr.onerror = function() {
              console.log('Error response from CORS ' + method + ' request to ' + url + ': ' + xhr.responseText);
          };

          xhr.send();
        };

        var server = 'http://10.100.3.21:5984/ass_support';

        corsCheck('GET', server);
        corsCheck('PUT', server);
        corsCheck('POST', server);
        corsCheck('HEAD', server);
//      corsCheck('DELETE', server);
    };
}]);

service.js

var _service = angular.module('assets.services', []);

_service.constant('dbConfig',{
    dbName: 'assets',
    dbServer: 'http://myCouchServerIp:5984/'
});

/**
 * Make PouchDB available in AngularJS.
 */
_service.factory('$db', ['dbConfig', function(dbConfig) {
    PouchDB.enableAllDbs = true;
    var localDb = new PouchDB(dbConfig.dbName);
    var remoteDb = dbConfig.dbServer + dbConfig.dbName;
    var options = {live: true};
    var syncError = function() {
        console.log('Problem encountered during database synchronisation');
    };

    console.log('Replicating from local to server');
    localDb.replicate.to(remoteDb, options, syncError);

    console.log('Replicating from server back to local');
    localDb.replicate.from(remoteDb, options, syncError);   

    return localDb; 
}]);

_service.factory('Machine', ['$q', '$db', '$rootScope', 'dbConfig', 
                   function($q, $db, $rootScope, dbConfig) {
    return {
        update: function(machine)  {
            var delay = $q.defer();

            var doc = {
               _id: machine._id,
               _rev: machine._rev,
               type: machine.type,
               customer: machine.customer,
               factory: machine.factory,
               lineId: machine.lineId,
               plcVersion: machine.plcVersion,
               dateCreated: machine.dateCreated,
               lastUpdated: new Date().toUTCString()
            };

            $db.put(doc, function(error, response) {
                $rootScope.$apply(function() {
                    if (error) {
                        console.log('Update failed: ');
                        console.log(error);
                        delay.reject(error);
                    } else {
                        console.log('Update succeeded: ');
                        console.log(response);
                        delay.resolve(response);
                    }
                });
            });

            return delay.promise;
        },
        getAll: function() {
            var delay = $q.defer();

            var map = function(doc) {
                if (doc.type === 'machine') {
                    emit([doc.customer, doc.factory], 
                            {
                                _id: doc._id,
                                customer: doc.customer, 
                                factory: doc.factory,
                                lineId: doc.lineId, 
                                plcVersion: doc.plcVersion,
                            }
                    );
                }
            };

            $db.query({map: map}, function(error, response) {
                $rootScope.$apply(function() {
                    if (error) {
                        delay.reject(error);
                    } else {
                        console.log('Query retrieved ' + response.rows.length + ' rows');
                        var queryResults = [];

                        // Create an array from the response 
                        response.rows.forEach(function(row) {
                            queryResults.push(row.value);
                        });

                        delay.resolve(queryResults);
                    }
                });
            });

            return delay.promise;
        },
        sync: function() {
            var remoteDb = dbConfig.dbServer + dbConfig.dbName;
            var options = {live: true};
            var syncError = function(error, changes) {
                console.log('Problem encountered during database synchronisation');
                console.log(error);
                console.log(changes);
            };
            var syncSuccess = function(error, changes) {
                console.log('Sync success');
                console.log(error);
                console.log(changes);
            };

            console.log('Replicating from local to server');
            $db.replicate.to(remoteDb, options, syncError).
                on('error', syncError).
                on('complete', syncSuccess);

            console.log('Replicating from server back to local');
            $db.replicate.from(remoteDb, options, syncError);       
        }
    };
}]);

_service.factory('dbListener', ['$rootScope', '$db', function($rootScope, $db) {
    console.log('Registering a onChange listener');
    $db.info(function(error, response) {
        $db.changes({
            since: response.update_seq,
            live: true,
        }).on('change', function() {
            console.log('Change detected by the dbListener');
            // TODO work out why this never happens
        });
    });
}]);

cache.manifest

CACHE MANIFEST

# views
views/machineForm.html
views/overview.html

# scripts
scripts/vendor/pouchdb-2.2.0.min.js
scripts/vendor/angular-1.2.16.min.js
scripts/vendor/angular-route-1.2.16.min.js

scripts/app.js
scripts/controllers/controller.js
scripts/services/service.js

index.html

<!DOCTYPE html>
<html lang="en" manifest="cache.manifest" data-ng-app="Assets">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Asset Management</title>

<script src="scripts/vendor/angular-1.2.16.min.js" type="text/javascript"></script>
<script src="scripts/vendor/angular-route-1.2.16.min.js" type="text/javascript></script>
<script src="scripts/vendor/pouchdb-2.2.0.min.js" type="text/javascript"></script>

<script src="scripts/app.js" type="text/javascript"></script>
<script src="scripts/services/service.js" type="text/javascript"></script>
<script src="scripts/controllers/controller.js" type="text/javascript"></script>
</head>
<body>
    <div id="content">
    <nav class="sidebar">
    <h3>Options</h3>
    <div>
        <a class="active" data-ng-href="#/">Overview</a>
        <a data-ng-href="#" data-ng-controller="SyncCtrl" data-ng-click="syncDb()">Synchronise</a>
        <a data-ng-href="" data-ng-controller="SyncCtrl" data-ng-click="checkCors()">Check CORS</a>
    </div>
    </nav>

    <section class="main">
        <div data-ng-view></div>
    </section>
    </div>  
</body>
</html>

overview.html

<h3>Installation Overview</h3>
<table>
    <tr>
        <th>Customer</th>
        <th>Factory</th>
        <th>Line Id</th>
        <th>PLC Version</th>
    </tr>
    <tr data-ng-repeat="machine in machines">
        <td>{{machine.customer}}</td>
        <td>{{machine.factory}}</td>
        <td><a data-ng-href="#/view/{{machine._id}}">{{machine.lineId}}</a></td>
        <td>{{machine.plcVersion}}</td>
    </tr>
</table>

machineForm.html

<h3>{{title}}</h3>
<form name="machineForm" data-ng-submit="save()">
    <div>
    <label for="customer">Customer:</label>
<div><input data-ng-model="machine.customer" id="customer" required></div>
    </div>

    <div>
    <label for="factory">Factory:</label>
    <div><input data-ng-model="machine.factory" id="factory" required></div>
    </div>

    <div>
<label for="lineId">Line ID:</label>
    <div><input data-ng-model="machine.lineId" id="lineId" required></div>
    </div>

    <div>
<label for="plcVersion">PLC Version:</label>
    <div><input data-ng-model="machine.plcVersion" id="plcVersion"></div>
    </div>

    <div><button data-ng-disabled="machineForm.$invalid">Save</button></div>
</form>

解决方案

Try changing your cache.manifest file to this:

CACHE MANIFEST

CACHE:
# views
views/machineForm.html
views/overview.html

# scripts
scripts/vendor/pouchdb-2.2.0.min.js
scripts/vendor/angular-1.2.16.min.js
scripts/vendor/angular-route-1.2.16.min.js

scripts/app.js
scripts/controllers/controller.js
scripts/services/service.js

NETWORK:
*

When using a manifest file, all non-cached resources will fail on a cached page, even when you're online. The NETWORK section tells the browser to allow requests to non-cached resources (they'll still fail while offline, of course).

这篇关于AngularJS / PouchDB应用程序停止同步到CouchDB的时候cache.manifest添加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆