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

尝试创build同步到Node.js服务器的Sencha-Touch-2应用程序; 下面的代码。 服务器使用同一IP上的另一个端口,所以这是跨域的。 (服务器使用Mongoose与MongoDB后端对话(未显示))

  • 如图所示使用JSONP代理可以从服务器读取数据,但在写入时会中断: “JSONP代理只能用于读取数据” 。 我猜JSONP代理编写器configuration只是写查询,不用于写同步(保存)。

  • Sencha文档声明,即使在Sencha论坛中讨论了跨域Ext.Ajax/Ext.data.Connection ,但是Ajax代理不能跨域, http : //www.sencha.com/forum/showthread。 PHP?17691-跨域-Ext.Ajax的-Ext.data.Connection

  • 我已经find了几种方法来做(跨域)JSON发布(例如, 移动应用程序使用Sencha的触摸 – JSON请求生成语法错误 ),但不知道如何将其作为一个作家在同步我的商店的代理作家。 Sencha Touch:创build/更新function的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' } ... 

商店

 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通过获取/读取封装在新启动的HTTP GET消息中的脚本标签中的数据部分地避开了这种情况。 通过这种方式,Sencha-Touch-2 JSONP代理可以从(跨域)服务器加载存储(读取/读取)。 但是,JSONP代理不能写入数据。 在1和2中描述了一种我已经适应的方法。

我的解决scheme使用JSONP代理来获取数据,但不能存储(它不能)。 相反,新logging和要保存或删除的logging在新启动的HTTP GET消息中与服务器通信。 即使只使用HTTP GET,服务器也会接受消息get (在上面的问题中描述), putdelnewGet被JSONP商店/代理load()

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 },