jQuery .ajax call returning error when accessing Java Spring service via domain name based URL - apache

My application's HTML5, jQuery Mobile frontend talks to Java server (Spring, Hibernate, MySQL). The application works fine on my notebook as well as in QA environment. On QA, I'm accessing the application using the server's IP address.
When I host the application in Live environment (the same server as QA but a different web app in Tomcat) and try to access it using URL with the domain name, $.ajax calls in the application return error.
One of the calls is as follows:
$.ajax({
type : "GET",
url : "http://www.smartcloudlearning.mobi:9080/SmartCloudLearningMobi/rest/resource/getResourceTypes",
cache : false,
async : false,
dataType : 'json',
success : function(rTypes) {
Alert("success!");
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown);
}
});
I get the following error in Firefox:
An error has occurred making the request: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://www.smartcloudlearning.mobi/js/jquery-1.7.1.min.js :: <TOP_LEVEL> :: line 4" data: no]
I get the following error in Chrome:
An error has occurred making the request: Error: NETWORK_ERR: XMLHttpRequest: Exception 101
In the server log, I see that the requested Spring service was successfully invoked but it looks like the client doesn't receive the data!
If I hit the URL
http://www.smartcloudlearning.mobi:9080/SmartCloudLearningMobi/rest/resource/getResourceTypes
directly in the browser, I get expected results! I sense that this is somehow due to how I forward server request from Apache to Tomcat.
The following are the lines in Apache / httpd server's httpd.conf file:
ProxyPass /SmartCloudLearningMobi http://www.smartcloudlearning.mobi:9080/SmartCloudLearningMobi
ProxyPassReverse /SmartCloudLearningMobi http://www.smartcloudlearning.mobi:9080/SmartCloudLearningMobi
Can anyone tell me what's amiss here? Much appreciated!
I managed to solve the problem:
The browser was giving the error on .ajax call because I had port number in my URL. The port number got carried over when I created 'live' URL from my QA URL. When I removed the port number from the .ajax call's URL, the call started returning success!
Jason Foglia, your statement "... and also the port..." nudged me to explore that angle... thanks a lot!

You're probably getting an error because of a security concept called "same origin policy" which doesn't allow you to call a service from a different domain. Or at least, disallow you from calling a method in that service.
Same discussion is found here - AJAX Cross Domain
You can however implement a cross-domain using JSONP - Wikipedia on JSONP
The solution is to change the datatype to JSONP:
$.ajax({
url:"http://www.smartcloudlearning.mobi:9080/SmartCloudLearningMobi...",
dataType: 'jsonp',
...
});

Try using an relative url:
If that doesn't work is the domain name the same as the url and also the port.
Browsers don't allow cross domains.
$.ajax({
type : "GET",
url : "/SmartCloudLearningMobi/rest/resource/getResourceTypes",
cache : false,
async : false,
contentType : "application/json"
dataType : 'json',
success : function(rTypes) {
Alert("success!);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown);
}
});

The browser was giving the error on .ajax call because I had port number in my URL. The port number got carried over when I created 'live' URL from my QA URL. When I removed the port number from the .ajax call's URL, the call started returning success!
Jason Foglia, your statement "... and also the port..." nudged me to explore that angle... thanks a lot!

Related

CORS blocking requests in Kotlin lambda but not in identically setup Node lambda

I have a lambda, written in Kotlin with Serverless and CORS just is not working. I feel like I've tried everything. I deployed a Node Lambda with identical sls.sh command and yaml files. The function looks like this
hello:
handler: handler.hello
events:
- http:
path: hello
method: post
cors: true
My responses look like this in both Node and Kotlin:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": "{\"id\": \"f9f76590-xxxx-xxxx-xxxx-9c8e99238f40\"}"
}
In the Node case this all works great. I make a fetch call like this and it works (omitted the Promise resolutions for brevity):
var makeRequest = function (data) {
fetch('https://{lambda URL}/hello', {
'headers': {
'content-type': 'application/json'
},
'body': JSON.stringify({ data }),
'method': 'POST'
})
}
In the Kotlin case I get this CORS error back
Access to fetch at 'https://{lambda URL}/hello' from origin
'http://127.0.0.1:8080' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
I try to "enable CORS" in the API Gateway panel but I get that it's already enabled:
And hit submit I get the error (invalid response status code)
When I hover over the error icon it says "Invalid Response status code specified".
Under Gateway Responses, under every sub item (Default 4XX, Default 5XXX, etc) there are response headers set. This is the same across my Node and Kotlin lambdas.
I'm completely out of ideas at this point.
The only potentially odd thing is I am noticing that in my Node request I see access-control-allow-origin: * in response headers in the browser network panel but in the Kotlin one I don't see it.
From this:
I can see that you haven't created Integration Response in your post method.
Try these configurations:
I discovered my CORS issue was because of server errors. If your server has an error and the API Gateway can't get a response then you get a CORS error because the Gateway itself doesn't have the CORS headers.
While the fix is easy (just handle that server error) it was hard to uncover. I wish this was documented better somewhere so hopefully this is found for others :)
For my case specifically, and why it didn't show up in Node but showed up in Kotlin, was because of types. the browser was sending a type Node automatically corrected the type (number to string) but Kotlin was expecting the type and threw a type error.

webpack dev-server: Avoid proxy errors on HTTP errors returned from proxy target

I have a Vue.js project where I have configured a webpack dev-server to proxy all requests to the UI to my backend server. Here is the relevant part of vue.config.js:
devServer: {
contentBase: PATHS.build,
port: 9000,
https: false,
hot: true,
progress: true,
inline: true,
watchContentBase: true,
proxy: {
'^/': {
target: 'http://127.0.0.1:8089',
secure: false
},
}
},
I've noticed that if the HTTP response code from http://127.0.0.1:8089 is anything other than 2xx then the proxy fails with the following error:
Proxy error: Could not proxy request /api/test from localhost:9000 to http://127.0.0.1:8089.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (HPE_INVALID_CHUNK_SIZE).
This also causes the HTTP response code from the request to localhost:9000 to be 500 for any error and all the information about what went wrong on the server side is lost. This is problematic as I want to be able to extract information from error responses to display to the user.
I know it's possible to do because I had it working on an older Angular project which I think was using Webpack 3 (am now using Webpack 4). I tried copying all the dev-server config from this project but it just doesn't seem to work here!
EDIT: I was wrong. The Proxy error does not occur on every bad response but only for one of the requests which is a multipart file upload. Still unable to reproduce this in a smaller example to put on github though so struggling to pinpoint the cause.
This error message comes from node_modules/#vue/cli-service/lib/util/prepareProxy.js, which define a onError callback for node-http-proxy;
So I did some experiment, make back-end api generate 400 404 500 response, but I didn't got this error.
After I happen to close back-end api, error arise:
Proxy error: Could not proxy request /hello from localhost:8080 to http://localhost:8081 (ECONNREFUSED).
I search in the doc and find these:
The error event is emitted if the request to the target fail. We do not do any error handling of messages passed between client and proxy, and messages passed between proxy and target, so it is recommended that you listen on errors and handle them
So the onError do not handle error code, is called only when request fail (500 response is still treated as a complete request, connection refuse is not)
Go back to your error message, [HPE_INVALID_CHUNK_SIZE] means bad request to the back-end api. In this issue, it gives an solution: add a keep-alive header:
devServer: {
publicPath: 'http://localhost:9090/front/static-dev/build/',
port: 9090,
proxy: {
'/**': {
target: 'http://localhost:8080',
secure: false,
changeOrigin: true,
headers: {
Connection: 'keep-alive'
}
},
open: true
}
I have finally found the problem, and I apologise, it was a lot more of a specific issue than I originally thought when I wrote the question.
Issue was to do with a request which was proxied to another server using the Spring RestTemplate:
e.g.
#PostMapping("/upload")
public ResponseEntity upload(#RequestParam("file") MultipartFile file)
throws Exception {
String baseUrl = serviceProperties.getAddress();
HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
return restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
}
The ResponseEntity returning from the rest template proxy contained the header "Connection: close" when the response was anything other than 200 which cause the connection to close and caused this request to fail to return anything which subsequently made the dev-server proxy fail on the UI.
Fixed this by not passing the response headers from the rest template proxy to the response:
#PostMapping("/upload")
public ResponseEntity upload(#RequestParam("file") MultipartFile file)
throws Exception {
String baseUrl = serviceProperties.getAddress();
HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
ResponseEntity response = restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
return new ResponseEntity<>(response.getBody(), response.getStatusCode());
}

Cross-domain requests does not work using Sencha Touch 2

I have an application which displays some articles. The application works perfectly on Wamp in localhost. I've uploaded my database management in an other server. I already configured my ArticleStore.js in JSONP but when I run my application the following error appears in the console :
Resource interpreted as Script but transferred with MIME type text/html: "http://[ip_address]:[port]/totos?_dc=1372152920457&keyword=&page=1&start=0&limit=25&callback=Ext.data.JsonP.callback1"
and :
Uncaught SyntaxError: Unexpected token : totos:1
When I clic on the url above I'm redirected to the view which display the following content :
{"articles_list":[{"id":"28","title":"Prixtel dope son service client avec le forfait Sumo"}],"total":1}
For sake of simplicity, I tested to display just the title of one article. Here's the JSON response for the line 1 when I clic on 'totos:1':
{"articles_list":[{"id":"28","title":"Prixtel dope son service client avec le forfait Sumo"}],"total":1}
Here's my ArticleStore.js content :
Ext.define("MyApp.store.ArticleListStore",
{
extend: "Ext.data.Store",
requires: ["MyApp.model.ArticleModel","Ext.data.proxy.JsonP"],
config: {
model: "MyApp.model.ArticleModel",
proxy: {
type: 'jsonp',
model: "MyApp.model.ArticleModel",
url: "http://62.23.96.124:81/totos",
},
reader: {
type: "json",
rootProperty: "articles_list",
totalProperty: "total"
},
},
autoLoad: true
}
});
When I was launched my resquest in localhost directly on Wamp server my JSON responses had the same syntax (The JSON tree architecture is the same). Here's an example :
{"articles_list":[{"id":"384","title":"Skype est disponible sur Windows Phone"}],"total":1}
I cannot see any difference between the two responses. However, I have an 'Unexpected token' error!. As you can see the two nodes 'articles_list' and 'total' have the same place in the JSON tree for the two examples. I don't understand why there is an syntax error. I'm really lost. Does anyone can help me, please ?
Thanks a lot in advance for your help.
Your server is not formatting the response correctly for JSON-P. JSON-P essentially needs your response to be embedded within a function, which is specified by the callbackKey property of your proxy:
proxy: {
type: 'jsonp',
url : "http://62.23.96.124:81/totos",
callbackKey: 'myCallbackKey'
}
Then, on your server, you need to use that parameter to wrap your response:
myCallbackKey({
"articles_list": [
{
"id":"28",
"title":"Prixtel dope son service client avec le forfait Sumo"
}
],
"total":1
})
You can learn more about this from the docs here: http://docs.sencha.com/touch/2.2.1/#!/api/Ext.data.proxy.JsonP.
You also will want to know a little more about the purpose of JSON-P, and how it works. Find out more here: What is JSONP all about?

XMLHttpRequest status 0

I'm using jquery ajax call and Chrome javascript console is spitting out an error:
XMLHttpRequest cannot load http://www.1luckypixel.com/eppy/fong_app/index.php/fb_login/login_user. Origin http://1luckypixel.com is not allowed by Access-Control-Allow-Origin.
I've done some searching and find a lot of info for "Origin NULL is not allowed by Access-Control-Allow-Origin." But this is actually giving my domain name as the un allowed origin. I'm not sure what the error means. Also the request goes to the server but doesn't come back and the data in the request isn't past.
Here is my code in case that helps:
$.ajax({
type : 'POST',
url : "<?= base_url(); ?>index.php/fb_login/login_user",
data: {
name:response.name , img:response.link+'/picture' , fb_id:response.id
},
beforeSend : function(thing,data) {
console.log('before', data);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
console.log('xmlhttprequest', XMLHttpRequest);
console.log('textStatus', textStatus);
console.log('errorthrown', errorThrown);
}
});
www.1luckypixel.com is not the same as 1luckypixel.com
Use a relative URL in your JavaScript, not an absolute one.
Better yet, pick one of the two hostnames to be canonical and redirect all the traffic from the other one to it (with an HTTP 301 status code).

DNS Lookup for localhsot failed. No such host is known

i did a break point on the method but it never goes there and also if paste the url in the web browser and hit enter and this is what i get in Firebug:
ReadResponse() failed: The server did not return a response for this request.
EDIT:
indeed that was typo, after correcting it and i still have no response, in FF i see the response
GET GetCustomer?method=jsonp1299253547713
http://localhost:2344/service1.svc/GetCustomer?method=jsonp1299253547713
Aborted
localhost:2344
?
what may be wrong ?
END EDIT
i have a created wcf services using json with padding (http://msdn.microsoft.com/en-us/library/cc716898(v=vs.90).aspx)
i have the code below that i am using to call the service, and this code is in html page withint th same project that i have created the wcf service.
$("#btn").click(function (event) {
$.getJSON('http://localhsot:2344/Service1.svc/GetCurrentUser?method=?', { },
function (data) {
debugger
alert(data);
});
//return false;
});
getting this error:
DNS Lookup for localhsot failed. No such host is known
Try renaming:
localhsot => localhost
You spelled localhost wrong. Look at your url and fix the spelling error.