4

Node.js サーバーに同期する Sencha-Touch-2 アプリを作成しようとしています。以下のコード。サーバーは同じ IP の別のポートを使用するため、これはクロスドメインです。 (サーバーは Mongoose を使用して MongoDB バックエンドと通信します (表示されていません))

このフォーラムや他の場所を数日間読んでいますが、行き詰まっているようです. どんな助けでも大歓迎です。

Node.js と resify サーバー

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

煎茶タッチ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);
                    },
...
4

1 に答える 1

2

Sencha-Touch-2 アプリでは、ブラウザーはクロスドメイン AJAX 呼び出しを禁止します (同一オリジン セキュリティ ポリシーに違反します)。これは、異なるドメイン、異なる IP アドレス、さらには同じ IP アドレスの異なるポートに関係します。JSONP は、新しく開始された HTTP GET メッセージのスクリプト タグにカプセル化されたデータを取得/読み取ることで、これを部分的に回避します。このようにして、Sencha-Touch-2 JSONP プロキシは (クロスドメイン) サーバーからストア (取得/読み取り) をロードできます。ただし、JSONP プロキシはデータを書き込むことができません。12 では、私が採用したアプローチについて説明します。

私のソリューションでは、JSONP プロキシを使用してデータを取得しますが、保存することはできません (できません)。代わりに、新しいレコード、および保存または削除されるレコードは、新しく開始された HTTP GET メッセージでサーバーと通信されます。HTTP GET のみが使用されますが、サーバーはメッセージget(上記の質問で説明)、putdelおよびを受け入れますnewGetJSONP store/proxy で使用され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
}

煎茶コントローラー

新しい

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
},
于 2012-09-30T10:20:46.907 に答える