从Sencha Touch 2到外部服务器的跨域更新



尝试创建一个与Node.js服务器同步的Sencha-Touch-2应用程序;下面的代码。服务器使用同一IP上的另一个端口,因此这是跨域的。(服务器使用Mongoose与MongoDB后端(未显示)进行通信)

  • 如图所示使用JSONP代理可以从服务器读取数据,但在写入时会中断:"JSONP代理只能用于读取数据">。我想JSONP Proxy编写器配置只是用来编写查询,而不是用来编写同步(保存)。

  • Sencha文档指出Ajax代理不能跨域,即使跨域Ext.Ajax/Ext.data.Connection在Sencha论坛中进行了讨论:http://www.sencha.com/forum/showthread.php?17691-跨域外部Ajax外部数据连接

  • 我已经找到了几种方法来做(跨域)JSON帖子(例如,移动应用程序使用Sencha Touch-JSON请求生成语法错误)但不知道如何将其作为一个写入程序集成到同步我的商店的代理中。Sencha Touch:用于创建/更新功能的ScriptTagProxy url似乎提供了指针,但这是ajax,显然不适合跨域。

我已经在这个论坛和其他地方读了几天了,但我似乎被卡住了。任何帮助都将不胜感激。

Node.js和restify服务器

var server = restify.createServer({
name: 'Server',
key: fs.readFileSync(root+'/'+'privatekey.pem'),
certificate: fs.readFileSync(root+'/'+'certificate.pem')
});
server.use(restify.bodyParser());
server.use(restify.queryParser());
function getMessages(req, res, next) {
Model.find(function (err,data) {
res.setHeader('Content-Type', 'text/javascript;charset=UTF-8');
res.send(req.query["callback"] + '({"records":' +  JSON.stringify(data) + '});');
});
}
function postMessage(req, res, next) {//not yet tested
var obj = new Model(); 
obj.name = req.params.name;
obj.description = req.params.description;
obj.date = new Date();
obj.save(function (err) {
if (err) throw err;
console.log('Saved.');
res.send('Saved.');
});
}
server.post(/^/atapp/, postMessage);
server.get(/^/atapp/, getMessages);
server.listen(port, ipaddr, function() {
console.log('%s: secure Node server started on %s:%d ...', Date(Date.now()), ipaddr, port);
});

Sencha Touch 2

型号

Ext.define('ATApp.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'name',  type: 'string' },
{ name: 'description', type: 'string' },
{ name: 'date',  type: 'date' },
{ name: '_id' }
...

Store

Ext.define('ATApp.store.Data', {
extend: 'Ext.data.Store',
requires: [
'ATApp.model.User',
'Ext.data.proxy.JsonP'
],
config: {
autoLoad: true,
model: 'ATApp.model.User',
storeId: 'Data',
proxy: {
type: 'jsonp',  
model: 'ATApp.model.User',
url: 'https://192.168.2.45:13017/atapp',
reader: {
type: 'json',
idProperty: '_id',
rootProperty: 'records',
useSimpleAccessors: true
},
writer: {
type: 'json',
allowSingle: false,
encode: true,
idProperty: '_id',
rootProperty: 'records'
...

控制器

onNewDataRecord: function (view) {
console.log('newDataRecord');
var now = new Date();
var record = Ext.create('ATApp.model.User', {
date: now,
name: '..',
description: '..'
});
var store = Ext.data.StoreManager.lookup('Data')
record.setProxy(store.getProxy());
store.add(record);
this.activateEditor(record);
},
...

在Sencha-Touch-2应用程序中,浏览器禁止跨域AJAX调用(这违反了同源安全策略)。这适用于不同的域、不同的IP地址,甚至同一IP地址上的不同端口。JSONP通过获取/读取封装在新启动的HTTPGET消息中的脚本标记中的数据来部分规避这一问题。通过这种方式,Sencha-Touch-2JSONP代理可以从(跨域)服务器加载存储(获取/读取)。但是,JSONP代理无法写入数据。在1和2中描述了一种方法,我对此进行了调整。

我的解决方案使用JSONP代理来获取数据,但不用于存储(它不能)。相反,新记录以及要保存或删除的记录在新启动的HTTPGET消息中与服务器通信。即使仅使用HTTP GET,服务器也接受消息get(如上所述)、putdelnew。CCD_ 6由JSONP存储/代理CCD_ 7使用。

Node.js服务器

//routes
server.get(/^/atapp/put/, putMessage);
server.get(/^/atapp/get/, getMessages);
server.get(/^/atapp/del/, delMessage);
server.get(/^/atapp/new/, newMessage);
function newMessage(req, res, next) {    
var obj = new Model();                  // Mongoose create new MongoDB object
obj.save(function (err,data) {
var x = err || data;
res.setHeader('Content-Type', 'text/javascript;charset=UTF-8');
res.send(req.query["callback"] + '({"payload":' +  JSON.stringify(x) + '});');
});                                     // send reply to Sencha-Touch 2 callback
}
function putMessage(req, res, next) {    
var q = JSON.parse(req.query.data);     // no reply: add error recovery separately
var obj = Model.findByIdAndUpdate(q.key,q.val);  
}
function delMessage(req, res, next) {
var key = JSON.parse(req.query.data);
Model.findByIdAndRemove(key);       // no reply: add error recovery separately
}

Sencha控制器

新建

onNewDataRecord: function (view) {
var control = this;
Ext.Ajax.Crossdomain.request({
url: 'https://192.168.2.45:13017/atapp/new',
rootProperty: 'payload',
scriptTag: true, // see [1](http://code.google.com/p/extjsdyntran/source/browse/trunk/extjsdyntran/WebContent/js/3rdparty/Ext.lib.Ajax.js?r=203)
success: function(r) { // process synchronously after response
var obj = r.payload;
var store = Ext.data.StoreManager.lookup('Data');
var key = obj._id // MongoDB document id
store.load(function(records, operation, success) { // add new record to store
var ind = store.findBy(function(rec,id) {
return rec.raw._id==key;
}); // identify record in store
var record = store.getAt(ind);
control.onEditDataRecord(view,record);
}, this);
}
});

保存

onSaveDataRecord: function (view, record) {
rec = {key:record.data.id, val: {}} // save template
var i; for (i in record.modified) rec.val[i]=record.data[i];
var delta = Ext.encode(rec); // only save modified fields
Ext.Ajax.Crossdomain.request({
url: 'https://192.168.2.45:13017/atapp/put',
params: {
data: delta,
},
rootProperty: 'payload',
scriptTag: true, // Use script tag transport
});
},

删除

onDelDataRecord: function (view, record) {
var key = record.data.id;
Ext.Ajax.Crossdomain.request({ // delete document in db
url: 'https://192.168.2.45:13017/atapp/del',
params: {
data: Ext.encode(key),
format: 'json'
},
rootProperty: 'payload',
scriptTag: true, // Use script tag transport
});
record.destroy(); // delete record from store
},

相关内容

  • 没有找到相关文章

最新更新