Since this morning all my applications using gapi are down.
I'm using:
https://apis.google.com/js/client.js
to communicate with the Endpoints of my Google Appengine applications, for example:
gapi.client.load('public', 'v2', function(){
gapi.client.public.organizations().execute(function(response){
console.log(response);
});
}, 'https://XXX.appspot.com/_ah/api');
As of today all calls are responded with the following error message:
[{"error":{"code":404,"message":"Not Found","data":[{"domain":"global","reason":"notFound","message":"Not Found"}]},"id":"gapiRpc"}]
My applications are not logging any errors.
I can reach the Endpoint API explorer (/_ah/api/explorer) without errors.
I can make HTTP-request calls without errors, e.g
https://XXX.appspot.com/_ah/api/public/v2/organizations
The "gapi"-object is loaded without errors. My "public" endpoint is also loaded and I can list all methods using the javascript console.
I have reported this error to Google.
Anybody else having this issue? Does anybody have any quick solutions or workarounds? Have I perhaps missed some Google updates or API-changes?
Thanks
It seems to be a general issue with the JS Client library at the moment, not limited to Endpoints APIs, but affecting all Google APIs.
https://code.google.com/p/google-api-javascript-client/issues/detail?id=136
Only real "work around" is not to depend on the JS Client Library (which had stability issues in the past as well) and construct the HTTP Requests yourself, which I know isn't a quick solution.
You can also try using the gapi.client.request method for direct REST requests which seems to be working for one of my endpoints APIs. (again, not a quick solution, but probably better/easier since you still have the authentication working via the client library).
gapi.client.request({
"path": "/public/v2/organizations",
"root": "https://XXX.appspot.com/_ah/api"
}).execute(function (response) {
console.log(response);
});
Edit: Update from the linked issue
They will be rolling back the broken update which will take several hours to complete (no exact ETA yet).
As a "quick" fix you can explicitely add the apiVersion to each request (careful: the B might change after the rollback, but it works now):
var request = gapi.client.public.organizations();
request.B.apiVersion = "v2";
request.execute(function (response) {
console.log(response);
});
Edit 2: Everything seems to be back to normal now.
The another workaround can be done by passing discovery document url.
Sample discovery document url is
url =
http://[application-id].appspot.com/_ah/api/discovery/v1/apis/[endpoint-api-name]/v1/rest
localHostURL =
http://localhost:8080/_ah/api/discovery/v1/apis/[endpoint-api-name]/v1/rest
Example :-
window.gapi.client.load("http://localhost:8080/_ah/api/discovery/v1/apis/[endpoint-api-name]/v1/rest").then(() => { Your promise return callback function })
or
window.gapi.client.load(" http://[application-id].appspot.com/_ah/api/discovery/v1/apis/[endpoint-api-name]/v1/rest").then(() => { Your promise return callback function })
Related
Keep in mind, I'm running an old version of AngularJS (1.0?), so things may have changed, but I have code that looks like:
promise = $http.get(urlFormattedString).success(function (data) {
data.forEach(function (result) {
//do something with result and $scope});
promises.push(promise);
$q.all(promises).then(function (data) {
//do something good when everything works!
};
When no errors are thrown, everything "works", but my question is what happens when one of the promises throws an error (say 1 out of 20)? Let's make this more interesting (and closer to my application) and assume that each promise is requesting data from a database (MongoDB in my case).
If I have to re-run everything, does that mean necessarily that all the data needs to be fetched again? Am I relying on the database to cache the data so the repeated requests run much faster? Or maybe the server (NodeJS in my case) caches the data? Along these lines, when are the data actually sent to the client from the server? Is it only upon success of all promises or is the data returned to the client from each promise separately? And if so, does Angular do the caching?
Just laying this out here makes me realize this is pretty complex and lots of scenarios to consider. Would appreciate any help or pointers to reading/documentation on this subject. Thanks!
Suggest you familiarize yourself with the network tab of your browser dev tools.
You can see every request made for all resources from html to images to scripts as well as ajax requests. This will give you a far better feel for how the app works in general
As for errors ... unless you implement error handling your app will simply fail for that request with no indication given to user that anything went wrong.
As for caching ... your ajax requests won't be cached client side and unless you have implemented caching mechaanisms on server they won't be cached there either
I'm currently working on a mobile app built on Cordova and Ionic. I am dealing with a third-party API (i.e. it cannot, and will not be changed for this app to work).
When a user of the app is unauthenticated - be that if their session has expired or otherwise - the API responds with an HTTP 401, with a WWW-Authenticate header.
In a browser while developing this is fine, but while on an iPhone, or in a simulator it does not appear, and the app has to reach the timeout period for the request. When that timeout is reached, the request is cancelled. This means that in the JavaScript, we simply get back a HTTP status of 0, with no real data to identify whether or not there was a timeout, or an authentication issue.
Currently, I've put in place some educated guesswork like checking if the phone has connectivity when a timeout occurs etc, but this is not an ideal solution as the user still has to wait for that timeout, and it's not always correct.
How can I check when the HTTP 401 dialog has appeared and is expecting a response? I need to be able to identify when an actual 401 occurs, and when a request simply times out.
If there is a method in JavaScript to accomplish then, then that'd be great. A native solution would also work, be it a plugin or otherwise.
I am dealing with the same issue at the moment.
The issue is that when a 401 is being returned, it has a WWW-Authenticate piece, which tells the browser to pop up that little popup for you to try again. This isn't handled "right" (depends on who you ask I guess) in the iOS web container, which results in Cordova never to see the request.
The cordova bug is logged here: https://issues.apache.org/jira/browse/CB-2415
I don't understand how such a major issue hasn't been resolved, yet. But I am sure there are some technicalities around it. If you check out the updates, you see that Tobias Bocanegra ( https://github.com/tripodsan/cordova-ios/commit/5f0133c026d6e21c93ab1ca0e146e125dfbe8f7e ) added a "quick hack" to solve the problem. Maybe that helps you further. It didn't help me in my situation.
What I did in my case for a temporary fix:
I passed the http requests into the loading modal, which has a cancel button. So, it is up to the user to cancel or just wait. It's horrible, but it worked in my case. (Internal app, etc.)
Well I am not sure why the third-party API woudn't send you normal HTTP error codes. If you are connecting to the API with the use of $http you can add response interceptors to it, for example read next article:
http://codingsmackdown.tv/blog/2013/01/02/using-response-interceptors-to-show-and-hide-a-loading-widget/
Within the next error handler code you can add some code to evaluate the HTTP status code:
function error(response) {
// Added code for specific HTTP error codes
if (response.status === 401) {
console.log('Received 401');
}
// get $http via $injector because of circular dependency problem
$http = $http || $injector.get('$http');
if($http.pendingRequests.length < 1) {
$('#loadingWidget').hide();
}
return $q.reject(response);
}
Also see the AngularJS documentation about interceptors.
A native solution would also work, be it a plugin or otherwise.
I had the same problem and I could fix it with the cordova http plugin. Just install it via ionic plugin add cordova-plugin-advanced-http (check documentation here). Then your xhttp calls will be done natively and not out of the webView. Then responses with a ´WWW-Authenticate´ headers will not timeout anymore and you can properly handle a 401
You can use it in your code like this:
try { // important since it will not work in dev mode in your browser (e.g. chrome)
if (cordova && cordova.plugin && cordova.plugin.http) {
var server_url = 'https://example.com';
var your_endpoind = '/auth-me-example';
cordova.plugin.http.useBasicAuth('some_user', 'and_password');
cordova.plugin.http.setHeader(server_url, 'Content-type', 'application/json');
cordova.plugin.http.get(server_url + your_endpoind, {}, {}, function (response) {
console.log('response: ', JSON.stringify(response));
}, function (response) {
console.error('error response: ', JSON.stringify(response));
});
}
} catch (e) {
console.error('could not make native HTTP request!');
}
PS: if you are using angular2+ npm install --save #ionic-native/http is also quite useful.
Due to circumstances beyond my control, Javascript is the only language option available for me. I'm a beginner and am not even sure if I'm approaching the problem in a "recommended" manner.
Simply put, a customer has setup a MarkLogicDB server online and has given me read-only access. I can query the server with the HTTP GET protocol to return an XML document that has to be parsed. I've been able to create a curl command to return the data I need (example below);
curl --anyauth --user USERNAME:PASSWORD \
-X GET \
http://test.com:8020/v1/documents?uri=/path/to/file.xml
The above returns the requested XML file. Can someone please show me how I could convert the above to javascript code? Additionally, how would I parse the data? Let's say I want to get all the info from a certain element or attribute. How can this be accomplished?
This would be trivial for me to do in Java/.NET, but after reading plenty of online tutorials on Javascript, my head is spinning. Every tutorial talks about web-browsers, but I'm doing this on a server environment (The parse.com CloudCode). There isn't any UI or HTML involved. For debugging, I just read the logs created with console.log().
https://parse.com/docs/cloud_code_guide#networking seems pretty clear, as far as it goes.
Parse.Cloud.httpRequest({
url: 'http://test.com:8020/v1/documents',
params: {
uri : '/path/to/file.xml'
},
success: function(httpResponse) {
console.log(httpResponse.text);
},
error: function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
}
});
But you'll also need authentication. The Parse.Cloud.httpRequest docs don't include any examples for that. If you have support with that vendor, ask the vendor about digest authentication.
If you're stuck you might try adding user and password to the httpRequest params and see what happens. It might work, if the developers of this stack followed the XMLHttpRequest convention.
Failing support from the vendor and existing functionality, you'll have to implement authentication yourself, in JavaScript. This works by generating strings that go into the request headers. These resources should help:
http://en.wikipedia.org/wiki/Digest_access_authentication
http://en.wikipedia.org/wiki/Basic_access_authentication
Basic auth is much easier to implement, but I'd recommend using digest for security reasons. If your HTTPServer doesn't support that, try to get the configuration changed.
I need to retrieve data from a web service (via SOAP) during a nightly maintenance process on a LAMP server. This data then gets applied to a database. My research has returned many options and I think I have lost sight of the forest for the trees; partially because of the mix of client and server terms and perspectives of the articles I have read.
Initially I installed node.js and node-soap. I wrote a simple script to test functionality:
var soap = require('/usr/local/lib/node_modules/npm/node_modules/soap');
var url = "https://api.authorize.net/soap/v1/Service.asmx?WSDL";
soap.createClient(url, function(err, client)
{
if(typeof client == 'undefined')
{
console.log(err);
return;
}
console.log('created');
});
This uses a demo SOAP source and it works just fine. But when I use the actual URL I get a 5023 error:
[Error: Invalid WSDL URL: https://*****.*****.com:999/SeniorSystemsWS/DataExportService.asmx?WSDL
Code: 503
Response Body: <html><body><b>Http/1.1 Service Unavailable</b></body> </html>]
Accessing this URL from a browser returns a proper WSDL definition. I am told by the provider that the 503 is due to a same-origin policy violation. Next, I researched adding CORS to node.js. This triggered my stepping back and asking the question: Am I in the right forest? I'm not sure. So, I am looking for a command-line, SOAP capable, CORS app (or equivalent) configuration. I am a web developer primarily using PHP and Javascript, so Javascript is where I turned first, but that is not a requirement. Ideas? Or, is there a solution to the current script error (the best I think I have found is using jQuery in node.js which includes CORS)
Most likely, this error belongs to your website server.
Please go through this link, it might be helpful.
http://pcsupport.about.com/od/findbyerrormessage/a/503error.htm
Also you can open your wsdl in web browser, search for soap:address location tag under services. And figure out correct url, you are trying to invoke from your script. Directly access this url in browser and see what are you getting.
I think I have a better approach to the task. I found over the weekend that PHP has a full SOAP client. I wrote the same basic login script in PHP and it runs just fine. I get a valid authentication code in the response to loginExt (which is required in further requests), so it looks like things are working. I will comment here after verifying that I can actually use the web service.
I'm working in a team split into front-end and back-end developers. Sometimes, the front-end wants to make some REST requests to a http address / REST-resource that isn't yet implemented.
In ngMockE2E there's a $httpBackend service that seems quite useful for this. The question is, how do I mock only some specific urls/rest resources?
I want most requests like e.g. GET /users.json to go through to the backend server as usual. But while waiting for e.g. GET /users/tommy/profile.json to get implemented (by the back-end guys), it would be nice to have some "pretend response", aka mocking, so we can keep working. How should one go about?
Thanks :)
try include this in your project:
app.config(function($provide) {
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
}).run(function($httpBackend) {
// make sure we have access to
$httpBackend.whenGET('*').passThrough();
// here use your mocking data using $httpBackend
});