I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general.
In particular, what I would like to be able to do is something along the lines of:
// Server-side:
App.publish('myCollection', -> collection.find({}))
// Client-side:
let myCollection = App.subscribe('myCollection')
let bob = myCollection.find({name: 'Bob'})
myCollection.insert({name: 'Amelie'}, callback)
All interaction with the server should happen in the background.
I very much like Meteor's pub/sub. I wonder if there is a way to get a similar workflow, using sails.js or just a socket library in general
Basically yes, at least about realtime sync between backend and frontend. Let's review what meteor's have and answer point by point.
Pub/sub
The Pub / Sub concept, as stated by Sabbir, is also supported by sails.js. Though the basics are slightly different :
In meteor, the client can subscribes to everything he wants, and the server control what it receives by only publishing to who he wants;
whereas in sails.js, the server both does subscribe some clients sockets and publish to all binded sockets
Note that, by default:
meteor contains the autopublish package that just notify every client without any kind of filtering. To acheive some filtering, you have to meteor remove autopublish then you can handle what will your client receive by adding a mongo request to it, like explained here.
sails by default, on its automatic "select" blueprints actions, auto-subscribes the calling socket to the events on the objects returned by the "select".
As a server-side conclusion:
Subscribe: just call findor findOne blueprint default action, through a socket (attaching some where filters or not) and your socket will automatically be subscribed to every events concerning returned objects => you don't have to code anything on the server, in most cases, for the Subscribe logic.
Publish: every blueprint default actions (create, update, destroy, add, remove) auto-publish to subscribed sockets => you don't have to code anything on the server, in most cases, for the Publish logic.
(Though, if you find yourself implementing some manual controller actions, sails API helps you publishing and subscribing easily)
Client handling
Therefore, with both meteor and sails, clients only receive what they're supposed to receive. Time for front-end now.
Philosophy
meteor in one hand, with it's isomorphic dimension, does provide a front-end connector by nature, exposing it's data-bound collections.
sails on the other hand, is front-end agnostic, and can be attacked by any http REST connector (JS or not), such as $http, $resource, or more advanced ones like Restangular.
Though, being aware of the complexity using raw sockets on their API (when it comes to session, CORS, CSRF and stuff), they developped a javascript socket.io wrapper called sails.io.js designed to be REST-like-over-socket, and just works like a charm.
Basically, The main difference is that meteor is one step higher-level than sails, because it provides the logic of syncing collections and objects.
All interaction with the server should happen in the background.
sails.io.js, the official front-end component, is just not that high-level. When it comes to Angular.js.
Though, you can find some community connectors that aim to, kinda, provide the same feature as mongo data-bound collections and objects. There is sails-resource, spinnaker or angular resource sails. I tried both of them, and I should say that I was disapointed. The abstraction level is so high that it just becomes annoying, IMHO. For example, with not-very-RESTful-friendly custom actions, like a login, it becomes very hard to adapt it for your needs.
==> I would advice to use a low-level connector, such as angularSails or (my prefered) https://github.com/janpantel/angular-sails, or even raw sails.io.js if you're not using Angular.
Edit: just foun a backbone version, by the sails' creator
It just works great, and believe me, the "keep my collection in sync with that socket" code is so ridiculous, that finding a module for this is just not worth it.
Some code please, stop talking
In particular, what I would like to be able to do is something along the lines of:
Server
Meteor
# Server-side:
App.publish('myCollection', -> collection.find({}))
Sails
//Nothing to do, just sails generate api myCollection
Client
Meteor
# Client-side:
myCollection = App.subscribe('myCollection')
Sails, with sails.io.js
(Here using lodash for convenience)
var myCollection;
sails.io.get('/myCollection').then(
function(res) {
myCollection = res.data;
},
function(err) {
//Handle error
}
);
sails.io.on('myCollection').function(msg) {
switch(msg.verb) {
case 'created':
myCollection.push(msg.data);
break;
case 'updated':
_.extend(_.find(myCollection, 'id', msg.id), msg.data);
break;
case 'destroyed':
_.remove(myCollection, 'id', msg.id);
break;
};
});
(I leave the find where and create to your imagination with [the doc])
All interaction with the server should happen in the background.
Well, Sails, only for angular, with sails ressources
I'm not pretty used to that process, so I leave you reading here or here, but once again I'd choose manual .on()method.
Since I asked this question, I've learned a few things and some new projects have popped up. I decided against sails.io, because when developing with React.js, most of the community's weight is behind webpack, but sails.io uses gulp. I realize these can be used together and there is even an npm package for this, but I wasn't too keen on making my stack bigger than it had to be, so I went with a simple express.js server that I could tailor to my needs.
In order to sync my data, I'm using rethinkdb which allows me to asynchronously watch the database for changes and then publish the changes to the clients through websockets.
I've set up a simple script where I keep an instance of a baobab tree on both the client and the server.
When the tree gets modified on the server, it sends transaction data to the appropriate clients through the websocket
The client merges the transaction with the tree.
This method does not make use of local storage and keeps the data in memory in the node.js process. The data in the transaction is also quite redundant.
The future plan has always been to set something up using redis and local storage ...
... until yesterday when I found deepstream.io!
This is a tool that does exactly what I want and need! Nothing more, nothing less.
Another project worth mention is meatier: "like meteor, but meatier". It is composed of many other well supported open source projects, so you could even pick and choose.
Related
I'm using the packages accounts-password and useraccounts:bootstrap and it all works fine, meaning the sign-on form creates a new doc in the Meteor.users collection. But I don't want any collection on the client facing app, hence I do have a second app running to which I successfully connect via DDP.connect() and I can exchange all necessary docs/collections via pub/sub and calling methods on the remote app.
The only thing that doesn't work is the useraccount doc. I've used (on the client app):
remote.subscribe('users', Meteor.userId(), function() {
});
and (on the remote app):
Meteor.publish('users', function() {
return Meteor.users.find({});
});
even though I'm not sure if there is a pub/sub already included in the package. Still, the doc is written to the local (client) app and not to the remote app.
How can I achieve this?
useraccounts:core simply makes use of Accounts.createUser on the server side (see this line) within a method called from the client-side (see this another line).
So the new user object is created from the server side and not from the client (though it flows all the way down to the client thanks to the DDP and default users subscriptions...).
If you're really looking to change the defaul behaviour provided by the Meteor core Accounts packages (accounts-base, accounts-password in this case...) you should try to override the Accounts.createUser method which is were all begins...
In any case be warned that the current user is published to the client by default: see these lines
Finally, to prevent useraccounts:core to use the Accounts API you could try to override the AtCreateUserServer method and deal with the creation of a new user on a remote application inside there.
Package accounts-base provide such functionality.
The accounts-base package exports two constructors, called AccountsClient and AccountsServer, which are used to create the Accounts object that is available on the client and the server, respectively.
Nevertheless, these two constructors can be instantiated more than once, to create multiple independent connections between different accounts servers and their clients, in more complicated authentication situations.
Documentation: Accounts (multi-server)
I'm trying to automate a Meteor app available online (namely, Meteor.com's account management - to add a collaborator to all 170+ organizations I'm a member of).
I've researched reverse engineering Meteor apps but haven't been able to figure out correctly from DDP messages what methods are available on the server.
Meteor methods can be seen among the WebSocket frames by looking for "msg":"method". For example, if you log into https://meteor.com, go to Organizations, and add a username to an organization in your Meteor account, you can see this in the WebSocket frame:
{
"msg":"method",
"method":"addOrganizationMember",
"params":["jspdf", "splendido"],
"id": "2"
}
(If the output looks uglier than that, vote for the Chrome team to implement this feature request for prettifying WebSocket frame dumps.) That method name, however, failed when running Meteor.call('addOrganizationMember', 'jspdf', 'splendido') in the console, with an error that the method wasn't found (404).
So you just want to check if the method exists first & then if it does, make the call?
I think you'd want something like:
if (Meteor.server.method_handlers.addOrganizationMember) {
Meteor.call('addOrganizationMember', 'jspdf', 'splendido')
})
For client methods, it'd be Meteor.connection._methodHandlers
Hopefully I understood, set me straight if I didn't.
When I write meteor methods for collections I usually put them in a shared directory so they can be simulated on the client for fast speeds. However is this secure? Should I put methods in the server directory and if so which kind of methods?
This is not the way meteor is supposed to work for the general case. You are supposed to implement most of your collection methods (update, insert, remove) client side only, and check the updates rights server side.
If you have a collection with some posts, do not make a Meteor.call('addNewPost', newPost). And the a Posts.insert(...) in the addNewPost meteor method server side. This would be the classic way with a REST API ; but this is meteor :)
You go client side directly for a Posts.insert(...). This will be displayed client side right away and will try to update the base server side.
Then server side, you have to set extensive permissions :
Posts.allow({
'insert': function(userId, doc) {
// Check if the user exists
// if he has the right to insert
// if what he tries to insert is ok for you
// ...
},
'update': function(userId, docs, fields, modifier) {
// same, width the fields, the doc, the user...
},
'remove': function(userId, docs) {
// same again
}
});
You can allow() or deny()on anything you can do on a collection. This may seem weird but this is the real basis of good latency compensation. It may be a HUDGE security breach if you do not know how to set up your permission as they need to be. But if you know how to do that, there are absolutely not security issue.
(my advice is to deny everything but the specific elements you want to allow)
So :
the user updates his database client side with a client side method : myCollection.update()
he sees the results
meteor does its magic to send it to the server
the server check if this is allowed
if yes, write in base and send to the other subscribers
if not, send a request to revert the change client side
yes. you can make it safe and have shared directory for collections. Meteor latency compensation feature works only if you have collections in both server and client.
if you are using a shared code for collections you must do these.
remove insecure, autopublish packages
use publish/subscribe
configure allow/deny rules for each collection
more on meteor security.
http://security-resources.meteor.com/
the past few weeks I've been hard at work with Angular, Node, TDD, Heroku, Amazon S3 etc. Trying to get a better picture of how a fully scalable SPA with a solid backend is built, working with grunt, bower, haven't dipped my toes in TDD using Jasmine yet, though I understand how the tests are being made through Karma, this is supposedly my next step.
One thing is sure: IT IS A LOT OF INFORMATION
On to the Questions/Rationale on working with all these technologies.
First things first, I played with
Angular App https://github.com/angular-app/angular-app
NG Boilerplate https://github.com/joshdmiller/ng-boilerplate
and read many dozens of posts etc.
I found NG Boilerplate to be most logical structured (as far as my understanding of these things go).
As a demo project (which evolved from something really small) I want to make a Single Page CRUD Application using:
NodeJS as backend
Express as a web app framework
NG Boilerplate as the Client
The app deployed to Heroku
MongoDB for DB
Amazon S3 for dynamic storage
Now I want to use Angular-Apps's (https://github.com/angular-app/angular-app) server as a backend to my NGBoilerplate kickstarter
I want to know how:
from what I see the client connects directly to MongoDB?
how does the angular client communicate back and forth to express ?
I read an interesting article http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application related to how the authentication works.
Long Story Short, without me asking a ton of questions, could someone please describe in detail the workflow of such an app? Getting the session, login, access to editing the content, tying express routes to angular routes (e.g. X route can be accessed by the admin only) etc. ##
there'a big blur in my head :).
In the last months I played a lot with these issues and questions and I got to the following conclusion:
For my purposes, I needed an app that relies almost entirely on Angular, without a separate backend, and the present backend should be from Angular.
Why? Because I want all of my eggs in one basket, I don’t want to configure a ton of stuff on a lot of different parts.
As a basis for my project I ended up using ng-boilerplate, as a boilerplate :), with some changes to the development process, Grunt tasks etc, this is for everybody to figure out, depending on each particular project.
Well, the main issue I’m gonna touch here is that, for a true backend, made in Angular, we need secure routes and a secure persistence method, a database.
For the app, I took advantage of the ng-boilerplate's modular and dependency aware structure, I think it’s perfect for a Angular app.
Anyhow, I’m gonna take things top to bottom (final product wise, the build env as I said above, it’s up to you, but ng-boilerplate is awesome), here we go.
On the upper layer we have the actual Angular app, made just the way we want
The server container, is a NodeJS server with express and other modules to take PARTIAL care of the routing on different browsers and devices (In my app, I made HTML5 routing that is augmented by express, .htaccess like settings whenever there’s a partial URL it should redirect to index where Angular will read the path requested and zapp you to that location)
For my case, the whole things runs on Heroku, on a Node.JS application, you can install several other things there if you want to.
Now, for the persistency, to have authentication and security, and NOT to rely on backend for that, I am using firebase (https://www.firebase.com/), there’s some great tutorials there to help you going and have true persistence in your Angular APP, with routes when you are logged in, access to custom tables/objects in DB when you are logged in etc. It’s the real deal.
If you don’t want to rely OAuth’s possible sites to log in with (Facebook, github, persona or twitter) and want custom emails and addresses you can do that directly with Firebase, to create accounts and delete them etc.
FIREBASE Angular Backend.
So, Firebase, just like they say on the site is a powerful API to store and sync data in realtime.
I don’t know exactly how to approach this, so I’m gonna start it with creating a Firebase database. Once we create it, in the backend we have several options, one of which is security.
{
"rules": {
".read": true,
".write": "auth != null"
}
}
Here, if we read the documentation on https://www.firebase.com/docs/security/security-rules.html we’ll learn that we can add rules for each ‘table' in our database, so we can have like 3 protected ’table’ objects and some that are not protected.
We can protect tables per user basis, per different rules, if logged in or not, we also have inheritance for rules etc, pleas read the documentation there, it really is a good read.
Now, for these rules to take effect we need to enable the Firebase Simple Login and select the desired login method, from Facebook, Twitter, Github, Persona, Email&Password and Anonymous.
For a real app, we need to write info to DB also as anonymous (user sessions etc) and also as logged (with either of the options above) to store and read information.
Me, I wanted to go the quick easy way and made a Facebook authentication, reading the docs there I made a quick Facebook app, and in the settings of the application on Facebook I’m putting Firebase’s backend https://www.dropbox.com/s/xcd4b8tty1nlbm5/Screenshot%202014-01-22%2013.51.26.png
This gives a interim link to login to Facebook and have access to ’tables’ that are otherwise locked if the rule is auth !=null.
NOW, onto the Angular backend.
Firebase provides a library for us to put in our app, and a SimpleLogin lib, also, for Angular, a factory service called AngularFire.
In my case, I made local firebaseService with use methods that connects to my DB:
angular.module('firebaseService', ['firebase'])
.service('firebaseService', function ($firebase, $rootScope) {
//Input data in Firebase
var URL = "https://glowing-fire-xxxx.firebaseio.com";
var tellFirebase = function(ID, JSON) {
users = $firebase(new Firebase(URL + '/' + ID));
users.details = JSON;
users.$save('details');
};
return {
addUser: function(ID, JSON) {
tellFirebase(ID, JSON);
if ($rootScope.debugStatus === true) {
console.log('Firebase Service .addUSer Called');
}
},
getUser: function(ID) {
if ($rootScope.debugStatus === true) {
console.log('Firebase Service .getUser Called');
}
}
};
})
From here we do our READ/WRITE, on the controller’s page I have this:
It’s worth noticing that I have a middleware service (storageManagement) where I switch between Firebase and MongoDB, to avoid confusion.
.controller( 'SomeCtrl', function SomeController( $scope, storageManagement, $firebase, $firebaseSimpleLogin ) {
/*===========================
* ==== FIREBASE LOGIN
* ===========================*/
var URL = "https://glowing-fire-XXXXX.firebaseio.com";
var users = new Firebase(URL);
$scope.auth = $firebaseSimpleLogin(users, function(error, user){});
if ($scope.auth.user == null) {
//$scope.auth.$login('facebook');
}
console.log($scope.auth);
//$scope.auth.$logout('facebook');
$scope.doLogin = function() {
console.log($scope.facebookemail);
console.log($scope.facebookpassword);
$scope.auth.$login('facebook');
$scope.$on("$firebaseSimpleLogin:login", function(evt, user) {
storageManagement.runFirebase();
});
/* example of logging in while asking access to permissions like email, user_list, friends_list etc.
* auth.$login('facebook', {
rememberMe: true,
scope: 'email,user_likes'
});*/
};
$scope.doLogout = function() {
$scope.auth.$logout();
};
});
I’m adding the $firebase service to my controller, and the $firebaseSimpleLogin one.
This here exposes to scope two buttons, login/logout, that popup the OAuth window from Facebook, with email/password setting you won't need to to go through this I think, for a full understanding please read the full docs at firebase.
SO, once we are logged, we can access tables described in the rules, if we choose email/password, actually even for Facebook or other methods, we can assign certain rules for certain IDENTITIES, so you could have a ADMIN table where you could save settings that get READ on page load to apply whatever you want.
Now, with routes, we can check for the $scope.auth status, if WE PUT IT IN $rootScope, and check for the status when going to a route, if the status checks, we get to that route and it gets populated with stuff from the DB, otherwise, even if someone hacks it’s way to that route it won’t see anything because there are no permissions to read that table for unauthorized/wrong email users.
This is loosely based on this article, http://www.ng-newsletter.com/posts/back-end-with-firebase.html … I had a hard time changing the mindset from what the guy wrote there, but, after ONE WHOLE day, of reading the docs (and setting up middleware, mind you) from Firebase I figured it out, and it works.
The connection to the DB is exposed like one BIG object where you can do whatever operations you want.
This isn't the most complete explanation, but it should get you well on your way to making some awesome things:D
The best example of this that I've come across is called angular-app.
It's very comprehensive and addresses all your needs. It's written by one of the authors of the fantastic book "Mastering Web Application Development with AngularJS".
https://github.com/angular-app/angular-app
From the github repo:
AngularJS CRUD application demo
Purpose
The idea is to demonstrate how to write a typical, non-trivial CRUD application using AngularJS. To showcase AngularJS in its most advantageous environment we've set out to write a simplified project management tool supporting teams using the SCRUM methodology. The sample application tries to show best practices when it comes to: folders structure, using modules, testing, communicating with a REST back-end, organizing navigation, addressing security concerns (authentication / authorization).
We've learned a lot while using and supporting AngularJS on the mailing list and would like to share our experience.
Stack
Persistence store: MongoDB hosted on MongoLab
Backend: Node.js
Awesome AngularJS on the client
CSS based on Twitter's bootstrap
Build
It is a complete project with a build system focused on AngularJS apps and tightly integrated with other tools commonly used in the AngularJS community:
powered by Grunt.js
test written using Jasmine syntax
test are executed by Karma Test Runner (integrated with the Grunt.js build)
build supporting JS, CSS and AngularJS templates minification
Twitter's bootstrap with LESS templates processing integrated into the build
Travis-CI integration
I need users to be able to post data from a single page browser application (SPA) to me, but I can't put server-side code on the host.
Is there a web service that I can use for this? I looked at Amazon SQS (simple queue service) but I can't call their REST APIs from within the browser due to cross origin policy.
I favour ease of development over robustness right now, so even just receiving an email would be fine. I'm not sure that the site is even going to catch on. If it does, then I'll develop a server-side component and move hosts.
Not only there are Web Services, but nowadays there are robust systems that provide a way to server-side some logic on your applications. They are called BaaS or Backend as a Service providers, usually to provide some backbone to your front end applications.
Although they have multiple uses, I'm going to list the most common in my opinion:
For mobile applications - Instead of having to learn an API for each device you code to, you can use an standard platform to store logic and data for your application.
For prototyping - If you want to create a slick application, but you don't want to code all the backend logic for the data -less dealing with all the operations and system administration that represents-, through a BaaS provider you only need good Front End skills to code the simplest CRUD applications you can imagine. Some BaaS even allow you to bind some Reduce algorithms to calls your perform to their API.
For web applications - When PaaS (Platform as a Service) came to town to ease the job for Backend End developers in order to avoid the hassle of System Administration and Operations, it was just logic that the same was going to happen to the Backend. There are many clones that showcase the real power of this strategy.
All of this is amazing, but I have yet to mention any of them. I'm going to list the ones that I know the most and have actually used in projects. There are probably many, but as far as I know, this one have satisfied most of my news, whether it's any of the previously ones mentioned.
Parse.com
Parse's most outstanding features target mobile devices; however, nowadays Parse contains an incredible amount of API's that allows you to use it as full feature backend service for Javascript, Android and even Windows 8 applications (Windows 8 SDK was introduced a few months ago this year).
How does a Parse code looks in Javascript?
Parse works through classes and objects (ain't that beautiful?), so you first create a specific class (can be done through Javascript, REST or even the Data Browser manager) and then you add objects to specific classes.
First, add up Parse as a script tag in javascript:
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.1.15.min.js"></script>
Then, through a given Application ID and a Javascript Key, initialize Parse.
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
From there, it's all object manipulation
var Person = Parse.Object.extend("Person"); //Person is a class *cof* uppercase *cof*
var personObject = new Person();
personObject.save({name: "John"}, {
success: function(object) {
console.log("The object with the data "+ JSON.stringify(object) + " was saved successfully.");
},
error: function(model, error) {
console.log("There was an error! The following model and error object were provided by the Server");
console.log(model);
console.log(error);
}
});
What about authentication and security?
Parse has a User based authentication system, which pretty much allows you to store a base of users that can manipulate the data. If map the data with User information, you can ensure that only a given user can manipulate specific data. Plus, in the settings of your Parse application, you can specify that no clients are allowed to create classes, to ensure innecesary calls are performed.
Did you REALLY used in a web application?
Yes, it was my tool of choice for a medium fidelity prototype.
Firebase.com
Firebase's main feature is the ability to provide Real Time to your application without all the hassle. You don't need a MeteorJS server in order to bring Push Notifications to your software. If you know Javascript, you are half way through to bring Real Time magic to your users.
How does a Firebase looks in Javascript?
Firebase works in a REST fashion, and I think they do an amazing job structuring the Glory of REST. As a good example, look at the following Resource structure in Firebase:
https://SampleChat.firebaseIO-demo.com/users/fred/name/first
You don't need to be a rocket scientist to know that you are retrieve the first name of the user "Fred", giving there's at least one -usually there should be a UUID instead of a name, but hey, it's an example, give me a break-.
In order to start using Firebase, as with Parse, add up their CDN Javascript
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
Now, create a reference object that will allow you to consume the Firebase API
var myRootRef = new Firebase('https://myprojectname.firebaseIO-demo.com/');
From there, you can create a bunch of neat applications.
var USERS_LOCATION = 'https://SampleChat.firebaseIO-demo.com/users';
var userId = "Fred"; // Username
var usersRef = new Firebase(USERS_LOCATION);
usersRef.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
if (exists) {
console.log("Username "+userId+" is part of our database");
} else {
console.log("We have no register of the username "+userId);
}
});
What about authentication and security?
You are in luck! Firebase released their Security API about two weeks ago! I have yet to explore it, but I'm sure it fills most of the gaps that allowed random people to use your reference to their own purpose.
Did you REALLY used in a web application?
Eeehm... ok, no. I used it in a Chrome Extension! It's still in process but it's going to be a Real Time chat inside a Chrome Extension. Ain't that cool? Fine. I find it cool. Anyway, you can browse more awesome examples for Firebase in their examples page.
What's the magic of these services? If you read your Dependency Injection and Mock Object Testing, at some point you can completely replace all of those services for your own through a REST Web Service provider.
Since these services were created to be used inside any application, they are CORS ready. As stated before, I have successfully used both of them from multiple domains without any issue (I'm even trying to use Firebase in a Chrome Extension, and I'm sure I will succeed soon).
Both Parse and Firebase have Data Browser managers, which means that you can see the data you are manipulating through a simple web browser. As a final disclaimer, I have no relationship with any of those services other than the face that James Taplin (Firebase Co-founder) was amazing enough to lend me some Beta access to Firebase.
You actually CAN use SQS from the browser, even without CORS, as long as you only need the browser to send messages, not receive them. Warning: this is a kludge that would make my CS professors cry.
When you perform a GET request via javascript, the browser will always perform the request, however, you'll only get access to the response if it was from the same origin (protocol, host, port). This is your ticket to ride, since messages can be posted to an SQS queue with just a GET, and who really cares about the response anyways?
Assuming you're using jquery, your queue is https://sqs.us-east-1.amazonaws.com/71717171/myqueue, and allows anyone to post a message, the following will post a message with the body "HITHERE" to the queue:
$.ajax({
url: 'https://sqs.us-east-1.amazonaws.com/71717171/myqueue' +
'?Action=SendMessage' +
'&Version=2012-11-05' +
'&MessageBody=HITHERE'
})
The'll be an error in the console saying that the request failed, but the message will show up in the queue anyways.
Have you considered JSONP? That is one way of calling cross-domain scripts from javascript without running into the same origin policy. You're going to have to set up some script somewhere to send you the data, though. Javascript just isn't up to the task.
Depending in what kind of data you want to send, and what you're going to do with it, one way of solving it would be to post the data to a Google Spreadsheet using Ajax. It's a bit tricky to accomplish though.Here is another stackoverflow question about it.
If presentation isn't that important you can just have an embedded Google Spreadsheet Form.
What about mailto:youremail#goeshere.com ? ihihi
Meantime, you can turn on some free hostings like Altervista or Heroku or somenthing else like them .. so you can connect to their server , if i remember these free services allows servers p2p, so you can create a sort of personal web services and push ajax requests as well, obviously their servers are slow for free accounts, but i think it's enought if you do not have so much users traffic, else you should turn on some better VPS or Hosting or Cloud solution.
Maybe CouchDB can provide what you're after. IrisCouch provides free CouchDB instances. Lock it down so that users can't view documents and have a sensible validation function and you've got yourself an easy RESTful place to stick your data in.