EDIT I posted an issue on this and it should be fixed in release 1.9.16 of Google AppEngine SDK.
https://code.google.com/p/googleappengine/issues/detail?id=11414
I am developing a service using Google Cloud Endpoints.
Both the REST and the RPC API works great when I deploy it on App Engine. However the strange thing is, when I test the service locally (localhost), the REST calls works fine, but I am having trouble with calls using RPC.
My method signature in the backend is:
#ApiMethod(name = "user.updateprofile", httpMethod = HttpMethod.POST)
public UserProfileDto updateProfile(#Named("sessionToken") String sessionToken, UserProfileDto profile) throws UnauthorizedException { return profile; }
For simplicity I am just returning the UserProfileDto directly.
I have tried to execute the following request locally:
POST http://localhost:4567/_ah/api/rpc?prettyPrint=false
Content-Type: application/json-rpc
Accept: application/json-rpc
{
"method": "mobilebackend.user.updateprofile",
"id": "gtl_1",
"jsonrpc": "2.0",
"params": {
"sessionToken": "12345",
"resource": {
"username": "foo",
"userPrivate": true
}
},
"apiVersion": "v1"
}
When I set a breakpoint in the updateProfile method, I see that the sessionToken is correctly 12345 however the username field is null and the userPrivate field is false even though I specified it as true. The instance of UserProfileDto (profile) is not null.
The problem is that it fails to inject the values into the fields of the DTO when using RPC calls localhost. When I test it on the deployed version it works fine, and when I use REST calls it works both on localhost and when deployed on App Engine.
When I change the url in the above request to target the deployed version of my application on app engine it works just fine. https://<app-name>.appspot.com/_ah/api/rpc?prettyPrint=false
I start the service on localhost using:
mvn appengine:devserver
Do I miss some configuration in order to call the Cloud Endpoints RPC methods localhost? Or is it not supported?
I should notice that I have also tried with the auto-generated iOS client library which is using RPC and it also fails with the same error as the service fails to inject the values into the fields of the DTO object.
I have tested release 1.9.17 of Google AppEngine SDK and can confirm that using objects in RPC POST requests now works fine.
Related
We currently have a Ionic v1 project that calls an API implemented as a Google App Engine application. This Ionic app runs with Ionic serve, PhoneGap, and when deployed to Android/iOS.
We are now trying to deploy to the web using Firebase hosting.
The initial HTML/JS code all runs correctly until we reach an $http.get call to the Google App Engine. What happens then is that the request reaches the GAE server and is processed correctly there with a response being sent back. But in the client code, the response.data property is the contents of the Firebase application’s index.html rather than the response that was supplied from GAE.
We don’t know why this is happening, or how to fix it, but here are some relevant facts:
When we run the app on a device using PhoneGap or via the Google Playstore, the URL by which we access GAE is the same URL if we were accessing GAE from a browser. But, when we run the app via “ionic serve” we must use a proxy to work around a CORS issue. What we do is to specify a simplified URL in the Ionic code, and then provide a mapping of that simplified URL to the GAE’s actual URL in a file called “ionic.project” which looks something like this:
{
"name": "proxy-example",
"app_id": "",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://cors.api.com/api"
}
]
}
When we attempt to deploy the app via either “firebase deploy” or “firebase serve” we must use the proxy version of the URL in our $http.get call. Otherwise the call does not reach the GAE server at all. It is not clear how Firebase knows to use “ionic.project” for the proxy mapping.
We are not using “Angularfire”, only the standard AngularJS library that is packaged with Ionic 1.x
Thanks for any help you can offer.
I am able to access the client server in Angular 5 from localhost:4200 with Cross-Origin concept but when I am deploying the app using ng build to Pivotal Cloud Foundry, getting error Failed to load resource: the server responded with a status of 404 (Not Found).
Not able to figure out the exact issue.
I am using package.config.json as -
{
"/api": {
"target": "https://benifit.cfapps.io/api",
"pathRewrite": {
"^/api": ""
},
"changeOrigin": true
}
}
Also, I am using cf push -b staticfile_buildpack portal-app for pushing my app to PCF. Please suggest where and what I am missing
You are referring to the proxy config file from angular-cli dev server. This file is only used for local development, to avoid cross-origin requests. You cannot use this proxy, after the app is deployed.
So in your case the Angular app will directly query your backend underneath the following path /api. So you have to ensure the api is available at the same host (in cloud foundry). When the api is only available under benifit.cfapps.io/api, you have to change the base path for your HTTP queries in the app and also take care to enable cross-origin requests on the api side.
I've made a weather app that makes an API call to freegeoip to locate your current location's coordinates, and then using those coordinates to connect to openweathermap API to fetch your current location's weather.
In development the app worked perfectly fine. But after deploying to Heroku, I seem to get what looks like a CORS error?
Console logs:
Mixed Content: The page at 'https://weather-react-drhectapus.herokuapp.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://freegeoip.net/json/'. This request has been blocked; the content must be served over HTTPS.
Link to Heroku app
EDIT:
Changing to https seems to work for the freegeoip API (https://freegeoip.net/json/), but doesn't work for the openweathermap API. This is the full console log I get:
GET https://api.openweathermap.org/data/2.5/weather?appid=95108d63b7f0cf597d80c6d17c8010e0&lat=49.25&lon=4.0333 net::ERR_CONNECTION_CLOSED
bundle.js:16 Uncaught (in promise) Error: Network Error
at e.exports (bundle.js:16)
at XMLHttpRequest.d.onerror (bundle.js:16)
Google Maps API warning: NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages#no-api-keys
Google Maps API error: MissingKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#missing-key-map-error
Just change API endpoint to use https instead of http.
https://freegeoip.net/json/ works well ;)
Update
Your updated question contains one more request. Unfortunately, api.openweathermap.org is not available over HTTPS. Thus, you need to reach it thru proxy under your control and forward response to your client. For more info, see this answer
If you apply this middleware it should start working correctly
app.use(function (req, res, next) {
if (req.headers['x-forwarded-proto'] === 'https') {
res.redirect('http://' + req.hostname + req.url);
} else {
next();
}
});
This is my scenario:
XMLHttpRequest cannot load http://phi.dev/api/login. Redirect from 'http://phi.dev/api/login' to 'http://localhost:8100/' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
I have a Aungular2/Ionic 2 App on local and a Laravel Web API for authenticating user.
if I call this Web API from my Angular2 Module, I get an exception as given above.
Note: In Chrome Network, I could my angular service is being called 2 times. First with Request Method: OPTIONS and second time with Request Method: Get, which returns Http 302.
Does anyone know how to resolve this issue.
Thanks in advance.
Because the request is external and because you are serving the application locally you will have CORS issues.
To avoid such issues locally (when using ionic serve), you have to setup a local proxy in the ionic configuration files.
Check your Ionic 2 project directory and locate the file ionic.config.json: it usually is in the root directory of the project (and need to be there, along with package.json and so on).
Open the file, and add this (do not forget to be SURE that the line BEFORE that one ends with a comma (,), since it's a json file):
"proxies": [
{
"path": "/server",
"proxyUrl": "http://phi.dev"
}
]
Now, in the section where are you are performing the HTTP request, replace the http://phi.dev with /server. I will give you an example here.
I do recommend you, however, to be aware that such edit will make your compiled app to NOT work, so you likely want to put a debug flag for testing and compiled environments, like this:
class MyServiceOrComponent {
private debug: boolean = true; // Set this flag to FALSE when you need to actually compile the app for any real device.
private server: string = this.debug ? "/server" : "http://phi.dev";
constructor(private http: HTTP) {
const login = "/api/login"; // don't to it exactly like that, make a static list or something like this to store paths.
let request = this.http.get(this.server + login).then((res) => {
console.log(res);
});
}
}
What happens, explained briefly, is that if you perform the HTTP request as "localhost" it will throw you an exception (because of the CORS policy). Such will happen only when you are running the application in your testing environment (localhost). To avoid such, you provide a proxy, so that the request will be valid.
I've coded an Java App Engine app that uses Cloud Endpoints. I want to talk to these endpoints from a Node.js app. Is it possible to use the google-api-nodejs-client for this purpose?
I've already tried this:
var googleapis = require('googleapis');
googleapis
.discover('myapiname', 'v1dev', {baseDiscoveryUrl: 'http://localhost:8888/_ah/api/discovery/v1/apis/'})
.execute(function(err, client) {
console.log(err);
console.log(client);
client.myapiname.domains.list().execute(function(err, resp) {
console.log(resp);
});
});
But the library does not discover my endpoint, the callback returns null for err and client looks like this:
{ clients: [],
ops: {},
authClient: null,
undefined:
{ apiMeta: '<html><head><title>Error 404</title></head>\n<body><h2>Error 404</h2></body>\n</html>',
authClient: null,
defaultParams: null } }
I've replaced my real api name with 'myapiname' and of course the URL http://localhost:8888/_ah/api/discovery/v1/apis/ is reachable (it returns me the right discovery JSON if I open it in the browser on the same computer).
have you tried the same code with code deployed on some vm on google app engine.
I tried the same with our app engine url and it works like charm.