i am building a Sencha Touch 2 Application with userspecific datasets.
Architecture of the App:
Sencha Touch App <=====> Java Server backend with REST Services
( many AJAX requests =) )
What i actually have is:
Login the user with username/password
The app gets initialized and the loginform comes into play. After submitting the form as a AJAX request, the server backend checks the userdata and calls the client callback function.
And what i want to do is:
The callback function should
create a cookie with the sessiontoken or
store the sessiontoken within the localstorage (http://docs.sencha.com/touch/2-0/#!/api/Ext.data.proxy.LocalStorage) or
store the sessiontoken within js variable
Okay, shouldn't be the problem.
But how can i achieve the following:
Most of the data is specific for one user and should be returned by the REST service if needed (by clicking on the navigation,...). How can i send the sessiontoken (see above) within every AJAX request - so the server can provide the suitable datasets (assuming the token is valid)?
Send cookies within AJAX requests
I have already read that cookies gets automaticly added to the request if the url is on the same space, right? The Java Server is on the same domain (localhost:8080) but the cookies aren't available - instead of requests on urls like 'app.json'. I thought that cross-domain-requests are really domain specific?
Send paramaters within AJAX requests
Because the cookies aren't avi i thought about the possiblity of 'manually' adding parameters to the ajax requests. The App will contain many AJAX requests and thats why i dont want to add the token manually - i tried to override the requests function of Ext.Ajax but i failed ;-( :
(function() {
var originalRequest = Ext.data.Connection.prototype.request;
Ext.override(Ext.data.Connection, {
request : function(options) {
alert("Do sth... like add params");
return originalRequest.apply(this, options);
}
});
})();
ERROR:
Uncaught Error: [ERROR][Ext.data.Connection#request] No URL specified
I also tried to add a listener
Ext.Ajax.add({
listeners : {
beforerequest : function( conn, options, eOpts ){
alert("Do sth... like add params");
}
}
});
ERROR:
Uncaught TypeError: Object [object Object] has no method 'add'
Any idea about how i can add the token?
Or any better way of handling these case?
Thanks!
Finally i successfully used:
function addAjaxInterceptor(context)
{
Ext.Ajax.on('beforerequest', function(conn, options, eOptions)
{
// add the param to options...
}, context);
}
Executed from the app (=> addAjaxInterceptor(this)).
But the following solution is more suitable for my situation i think:
Ext.Ajax._defaultHeaders = {
// params as json
};
(Cause Ext.Ajax is a singleton object and i dont change the params for every request)
Related
I am trying to get the axios to wait until one extra call in the interceptor finishes. So I am using NuxtJS as a frontend SPA and API in Laravel 8.
I've tried a lot of different things over the course of last ~ 4 days but nothing seems to be working.
THE GOAL
I need my axios REQUEST interceptor to check for existence of the cookie. If cookie is not present I need to make an API call first to grab the cookie and then we can continue with any other request.
WHAT I AM DOING?
So basically I have Axios interceptor for the requests that will call cookie endpoint if the cookie doesn't exist.
I am also saving cookie request promise to be reused in case there are multiple calls and the cookie still is not there.
PROBLEM
While it was supposed to just call cookie API first and everything else after I am mostly getting two results in different variations of the attached code.
A) I am making an extra cookie call but it is not in the required order so I still end up hitting laravel endpoint multiple times without cookies which causes extra sessions to spawn.
B) It is not making any calls at all (attached example).
Does anyone know what in the world I am confusing here?
export default function ({$axios, redirect, $cookiz, store}) {
$axios.onRequest(async request => {
// make sure that XSRF cookie exists before we make aby calls to prevent backend from
// creating multiple session when page on load calls more than one endpoint, if we don't have
// that cookie we will first have to get it and then call the rest of the endpoints
const xsrfCookie = $cookiz.get('XSRF-TOKEN')
if (xsrfCookie === undefined || xsrfCookie === null || xsrfCookie === '') {
await store.dispatch('login/getXsrfCookie')
$axios.request(request)
}
$axios.request(request)
})
}
getXsrfCookie(context) {
if (context.state.xsrfCookiePromise instanceof Promise) {
return context.state.xsrfCookiePromise
}
const xsrfCookiePromise = this.$axios.get('/csrf-cookie').then(response => {
context.commit('setXsrfCookiePromise', null)
console.log('This is the cookie response', response)
})
context.commit('setXsrfCookiePromise', xsrfCookiePromise)
return context.state.xsrfCookiePromise
}
I don't know anything about nuxt, and have only a vague idea about axios interceptors, but just looking at the code...
I think you want to persist a cookie, not the promise for a cookie.
I don't think you need to involve the store.
I think you can do that with your cookie plugin. If I'm right about that, using the set method is what you need. (you might need an options param, described here)
async getXsrfCookie() {
if (!$cookiz.get('XSRF-TOKEN')) {
// the op should double check which part of the response to persist, whether to stringify it, etc.
const response = await this.$axios.get('/csrf-cookie');
$cookiz.set('XSRF-TOKEN', response.data);
}
}
export default function ({$axios, redirect, $cookiz, store}) {
$axios.onRequest(async request => {
await getXsrfCookie();
return $axios.request(request)
})
}
I am new to Nodejs so excuse me for any mistake .. :)
Let me explain what i am trying to do :
basically i am making a push notification service for my platform .. i will explain further..
I have two NodeJs servers (using express) :
SERVER 1 :
it gets everything needed from the database such as ( device registration , identifier ..) and should send to the second server.
SERVER 2 : This server Receives a JSON ( contains everything i need ) to create the FCM and APNS payload and then send to the convenient provider (FCM,APNS).
what i am using : i am using axios to send POST requests.
The issue : since the 1st server will be sending big amount of requests ( usually 5K or more -- it's dynamic) at the same time , axios cannot handle that , and I've tried many other alternatives to axios but faced the same thing.
My question : How can i send that amount of requests without any issues ?
PS: when i send few requests ( 100 or bit more) i face no errors ...
I hope everything is clear and i would really appreciate any help.
Code Example of the Request with Axios :
PS: it always falls in the "[Request Error] ..."
try
{
axios.post(endpoint,{sendPushRequest})
.then( response => {
console.log(response.data);
})
.catch( er => {
if (er.response) {
console.log("[Response Error] on sending to Dispatcher...");
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(er.response.data);
console.log(er.response.status);
console.log(er.response.headers);
} else if (er.request) {
console.log("[Request Error] on sending to Dispatcher...");
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
} else {
// Something happened in setting up the request that triggered an Error
console.log('[Error]', er.message);
}
console.log(er.config);
});
}
catch (e) {
console.log('[ Catch Error]', e);
}
Usually, for doing this kind of asynchronous stuff you should use any queuing service as if the second server gets busy which it might in case of handling such a huge number of rest APIs your user would miss the notification.
Your flow should be like:
SERVER 1: it gets everything needed from the database such as ( device registration, identifier ..) and should push/publish to any queuing service such as rabbitMQ/Google pubsub etc.
SERVER 2: Instead of having rest APIs, this server should pull messages from the queue recursively and then Receives a JSON ( contains everything I need ) to create the FCM and APNS payload and then send to the convenient provider (FCM, APNS).
This is beneficial because even if anything happens to your server like busy/crashes the message would persist in the queue and on restarting the server you would be able to do your work(sending a notification or whatever).
In working with the Angular docs / tutorial on the in-memory web api, I want to return some JSON values that indicate the success or failure of a request. i.e.:
{success:true, error:""}
or
{success:false, error:"Database error"}
But, the code in the example for the in-memory-data.service.ts file only has the one method: createDb().
How do update that service code to respond to a PUT/POST/DELETE request differently than a GET?
Note: In real-life / production, the backend will be PHP, and we can return these values any way we want (with the correct status codes). This question is specifically directed at making the In Memory Web API mock those responses.
Example:
Executing:
return = this.http.post(url,someJsonData,httpHeaders);
I would want return to be:
{success:'true',id:1234} with an HTTP Status code of 200.
Later, to delete that record that was just created:
url = `/foo/` + id + '/'; // url = '/foo/1234/';
this.http.delete(url);
This wouldn't really need a JSON meta data response. An HTTP Status code of 200 is sufficient.
How do update that service code to respond to a PUT/POST/DELETE
request differently than a GET?
The server will always respond to the requests that you have made. So if you fire an Ajax request it may be one of the known HTTP Methods (like POST, GET, PUT...). Afterwards you'll wait for the answer.
/** POST: add a new hero to the database */
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
.pipe(
catchError(this.handleError('addHero', hero))
);
}
/** GET: get a new hero from the database */
getHero (heroId: number): Observable<Hero> {
return this.http.get(this.heroesUrl + '/' + heroId)
}
I found the answer I was looking for: It's HttpInterceptors.
This blog post and the corresponding github repo demonstrate exactly how to simulate CRUD operations in Angular 2/5 without having to setup a testing server.
I am trying to develop an app which sends a HTTP POST request to a NodeJS server (on the localhost). I am using the networking library 'Alamofire' just to try and simplify things.
My issue arises when I try and send multiple requests, I set up a simple button which sends the post request. When I run the app i can click the button and see that it sends the post requests when I click it, but only for the first 4 button presses/post requests.
It may be possible that my server is not set up correctly and not sending a response back or something along those lines.
I get 4 post's each time i open the app - everytime i close and re open the app i get another 4.
The same goes for when I restart the server.
I have tested the server using a pre-existing app (HTTP utility) and it appears to work fine.
When I use Alamofire i use JSON encoding, could this cause the issue???
Here's my swift code:
import UIKit
import Alamofire
class ViewController: UIViewController {
#IBAction func postBTN(sender: AnyObject) {
post(["xx":[10]])
}
override func viewDidLoad() {
super.viewDidLoad()
}
func post(postParrams: [String : AnyObject]) {
Alamofire.request(.POST, "http://10.0.0.10:3000", parameters: postParrams, encoding: .JSON)
}
}
UPDATE *** I added the following code below the 'Alamofire.request' to print the response data:
.validate()
.responseJSON { response in
print(response.request)
print(response.response)
print(response.result)
switch response.result {
case .Success:
print("Validation Successful")
case .Failure(let error):
print("the error is", error)
}
}
The error code that prints is:
the error is Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x7fd5a3d0e170 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://localhost:3000/, NSErrorFailingURLKey=http://localhost:3000/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
From this i gather that the response result is a 'failure' and there are 2 error codes: Code=-1001, CodeKey=-2102
I have an AngularJS application and I want to cache the REST service responses. I found some libraries like angular-cached-resource which can do this by storing the data into the local storage of the web browser.
But sometimes I do some POST / PUT / DELETE REST calls and then some of the REST previously cached service responses need to be performed again. So it seems that it is possible to delete the cached responses then and the call will be sent to the server next time.
But what about if the server sends me in HTTP Header some values like the expires or the etag? I have to read the HTTP Header and react by myself or is there a library in AngularJS which can also handle this?
So if I should hit the server and not read the cache of the local storage is dependent on the HTTP Header Cache fields and if there are any PUT / POST / DELETE calls which have the response that for example "reload of every user settings element" are needed. So I have to take this response and create a map which tells me that for example REST services A, C and F (user settings related stuff) needs to hit the server again next time when they are executed or if the Cache expires from the HTTP Headers.
Is this possible with an AngularJS library or do you have any other recommendations? I think this is similar to Observer or PubSub Pattern, isn't it?
One more thing: Is it also possible to have something like PubSub without using a cache / local storage (so also no HTTP Header Cache controls)? So I can not call the REST service, because then it would hit the server, which I do not want in some circumstances (response from a previous REST call which returns me the event "reload of every user settings element").
You can try something like this.
app.factory('requestService', ['$http', function ($http) {
var data = {};
var service = {
getCall : funtion(requstUrl, successCallback, failureCallback, getFromCache){
if(!getFromCache){
$http.get(requstUrl)
.success(function(data){
successCallback(data);
data.requstUrl = data;
})
.error(function(){
failureCallback(data);
})
}else{
successCallback(data.requstUrl);
}
},
postCall : function(requestUrl, paramToPass, successCallback, failureCallback, getFromCache){
if(!getFromCache){
$http.post(requestUrl, paramToPass)
.success(function(data){
successCallback(data);
data.requstUrl = data;
})
.error(function(data){
failureCallback(data);
})
}else{
successCallback(data.requstUrl);
}
}
};
return service;
}]);
This is just a simple code I wrote to implement your concept. I haven't tested it and is all yours.