How to respond server-side to routes using Meteor

2020-04-21 08:25发布

问题:

I'm sending a file from client-side to server side using XHR:

$(document).on('drop', function(dropEvent) {
    dropEvent.preventDefault();
    _.each(dropEvent.originalEvent.dataTransfer.files, function(file) {
        // ...
        xhr.open('POST', Router.routes['upload'].path(), true);
        xhr.send(file);
    });
})

Now I want to respond to this POST server-side and save the file to disk. The docs only seems to talk about handling things client-side; I don't even know how to get a hook on the server-side.

All I have for routes right now is this:

Router.map(function() {
    this.route('home', {
        path: '/'
    });

    this.route('upload', {
        path: '/upload',
        action: function() {
            console.log('I never fire');
        }
    });
});

With connect, I could do:

Connect.middleware.router(function(route) {
    route.post('/upload', function(req, res) {
        // my server-side code here
    });
});

Is there anything similar for Iron-Router?


Digging through the internals, I discovered Meteor is using connect under the hood, and I can do something like this:

WebApp.connectHandlers.use(function(req, res, next) {
    if(req.method === 'POST' && req.url === '/upload') {
        res.writeHead(200);
        res.end();
    } else next();
});

But I have no idea how to get the user in this context.

回答1:

By default, your routes are created as client side routes. This means, a link to that route will be handled in the browser vs. making a server request. But you can also create server side routes by providing a where option to the route. The handler for the server side route exposes the request, response, and next properties of the Connect object. The syntax has changed a little from 0.5.4 to the dev branch so I'll provide both examples depending on which you're using:

v0.5.4

Router.map(function () {
  this.route('upload', {
    where: 'server',
    handler: function () {
      var request = this.request;
      var response = this.response;
      // do whatever
    }
  });
});

dev

Router.map(function () {
  this.route('upload', {
    where: 'server',
    action: function () {
      var request = this.request;
      var response = this.response;
      // do whatever
    }
  });
});


回答2:

You can upload file with use of EJSON and normal meteor "methods" this way you will be able to get access to user data because it is visible only inside methods and publish functions on server side

this video tutorial may be a good start

also package CollectionFS provides some upload functionalities. It is now little outdated, but idea stays the same.



回答3:

The same people who brought you iron-router also have meteor-file which will do the file transfer for you, or you can use as an example for your own implementation



回答4:

Meteor Router (now deprecated) has server side routing support:

Meteor.Router.add('/upload', 'POST', function() {
  // do stuff
});