简体   繁体   English

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

[英]Cross-domain Update from Sencha Touch 2 to external server

Trying to create a Sencha-Touch-2 app syncing to a Node.js server; 尝试创建一个同步到Node.js服务器的Sencha-Touch-2应用程序; code below. 下面的代码。 The server uses another port on the same IP, so this is cross-domain. 服务器使用同一IP上的另一个端口,因此这是跨域的。 (The server uses Mongoose to talk to a MongoDB back-end (not shown)) (服务器使用Mongoose与MongoDB后端进行对话(未显示))

I've been reading this forum and elsewhere for a couple of days, but I seem to be stuck. 我已经在这个论坛和其他地方阅读了几天,但是我似乎陷入了困境。 Any help would be much appreciated. 任何帮助将非常感激。

Node.js and restify server 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 Sencha Touch 2

Model 模型

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'
...

Controller 控制者

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);
                    },
...

In Sencha-Touch-2 apps, the browser prohibits cross-domain AJAX calls (which violate the same-origin security policy). 在Sencha-Touch-2应用程序中,浏览器禁止跨域AJAX调用(这违反了同源性安全策略)。 This pertains to different domains, different IP addresses and even different ports on the same IP address. 这涉及不同的域,不同的IP地址,甚至是同一IP地址上的不同端口。 JSONP circumvents this partly by fetching/reading data encapsulated in a script tag in a newly initiated HTTP GET message. JSONP通过获取/读取封装在新启动的HTTP GET消息中的脚本标签中的数据来部分地避免此情况。 In this way the Sencha-Touch-2 JSONP proxy can load a store (fetch/read) from a (cross domain) server. 这样,Sencha-Touch-2 JSONP代理可以从(跨域)服务器加载存储(获取/读取)。 However, the JSONP proxy cannot write data. 但是,JSONP代理无法写入数据。 In 1 and 2 an approach is described which I have adapted. 12中描述了一种我已经适应的方法。

My solution uses the JSONP proxy to fetch data, but not to store (which it can't). 我的解决方案使用JSONP代理来获取数据,但不存储(它不能存储)。 Instead, new records, and records to be saved or deleted are communicated with the server in a newly initiated HTTP GET message. 而是,新记录以及要保存或删除的记录在新启动的HTTP GET消息中与服务器通信。 Even though only HTTP GET is used, the server accepts message get (described in the question, above), put , del and new . 即使仅使用HTTP GET,服务器也接受消息get (在上面的问题中描述), putdelnew Get is used by JSONP store/proxy load() . Get由JSONP store / proxy load()

Node.js Server 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 Controller Sencha控制器

New

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);
        }
    });

Save 保存

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

Delete 删除

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM