问题描述
尝试将您的cache.manifest文件更改为此:
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:
*
使用清单文件时,即使您处于联机状态, 所有 非缓存资源也会在缓存页面上失败。NETWORK部分告诉浏览器允许对非缓存资源的请求(当然,它们在脱机时仍然会失败)。
解决方法
我有一个使用AngularJS编写的单页Web应用程序。它使用PouchDB复制到CouchDB服务器,并且工作正常。
当我尝试通过添加cache.manifest将网页转换为脱机使用时出现问题。突然,无论是脱机工作还是联机工作,所有复制任务都会引发错误并停止工作。
在Chrome中,它只是说“ GET … myCouchIP / myDB /?_ nonce = CxVFIwnEJeGFcyoJ net ::
ERR_FAILED”
在Firefox中,它还会引发错误,但会提到请求已被阻止-尝试启用CORS。
根据PouchDB设置页面上的说明,在远程CouchDB上启用了CORS。另外,它在不使用cache.manifest的情况下也可以正常工作(即,它对我的办公桌,服务器和VM之间的所有不同IP地址都非常满意-
它是一个原型,因此目前没有域名)。
顺便说一句,目前我不使用任何身份验证。管理员方有效。
那么添加cache.manifest时会发生什么变化?线索感激不尽。提前致谢。
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','$routeParams',$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',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,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},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,syncError).
on('error',syncError).
on('complete',syncSuccess);
console.log('Replicating from server back to local');
$db.replicate.from(remoteDb,syncError);
}
};
}]);
_service.factory('dbListener',['$rootScope',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>