AJAX 504 when calling ASP.NET Web API - ajax

My AJAX call is returning a 504 error when calling an ASP.NET Web API action.
More info:
Here's my API action:
public HttpResponseMessage Get(string fileName, int feedID)
{
try
{
// create file...
return new HttpResponseMessage { Content = new StringContent("Complete."), StatusCode = HttpStatusCode.OK };
}
catch (Exception ex)
{
Log.WriteError(ex);
throw new HttpResponseException(new HttpResponseMessage
{
StatusCode = HttpStatusCode.InternalServerError,
Content = new StringContent("An error has occurred.")
});
}
}
Here's my AJAX call:
$.ajax({
url: url,
type: 'GET',
success: function () {
$("#lblProgressDownload").hide();
window.open("Previews/" + fileName);
},
error: function (xhr, status, error) {
$("#lblProgressDownload").hide();
alert("Error downloading feed preview: " + error);
}
});
I get a 504 error (viewed in fiddler/ chrome console) when the file takes too long to create. The "error" parameter in the error callback doesn't return anything.
I only get the 504 error when it's hosted - on my dev it works fine.
How do I prevent this 504 error?
Note, I already tried changing the executionTimeout property in my web.config, as well as the ajax timeout. Neither worked.

HTTP error 504 is a gateway timeout:
The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI [...] in attempting to complete the request.
I suspect that means there is a proxy or gateway somewhere between you and the production server, but not your dev server, which is why it fails on the one but not the other.
Your choice is either to make your server code fast enough that it doesn't trigger the timeout, or get whoever is running the proxy server to relax their timeout restrictions (assuming it's something that you or your company controls).

Related

Ajax.BeginForm OnFailure return empty result when connecting via HTTPS

When connecting via a non-secured protocol (http), my MVC 5 web application returns the error message properly. But the moment I connect via https, the error message is blank. Thought? NOTE: I try json return also. Thanks!
Browser debugger output
HTTP
HTTPS
MVC Controller:
string message = string.Join(" ", errors);
Response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
return new HttpStatusCodeResult(Response.StatusCode, string.Join(" ", message));
Script:
function ajaxOnFailure(response, status, error) {
debugger;
if (response.status == 500) {
error = "An internal error has occurred. Please try again. If the problem persists, please contact IT."
}
toastr.error("", error);
}
I ended up using a workaround. Instead of return a fail response, I return OK response and determine the type of message via jquery. It would have been nice if a fail response return the message via https.

Invalid character returned in IE but not in Firefox and Chrome

I'm using fetch to return a JSON payload to a React SPA. My web server backend is ASP.NET Core 2.0. I recently updated to ASP.NET Core 2.0 and for the life of me can't figure out why IE no longer works with the web application.
The fetch is pretty straight forward.
fetch(getApiPath() + url, {
credentials: 'include'
})
.then(function(response){
if (response.status === 401 && history) {
history.push("/login")
throw new Error('Redirecting to login');
} else if (response.status === 200) {
return response.json();
} else {
throw new Error(response.statusText);
}
})
.then(success)
.catch(function(e) {
console.log(e)
});
The server end is also pretty straight forward.
[Authorize]
[Route("/dashboard")]
public object Index()
{
Log.Debug("Index");
return new { dashboard = _dashboard, authenticated = HttpContext.User.Identity.IsAuthenticated };
}
The problem manifests itself in a "Invalid Character" error in IE. This works fine in Chrome and Firefox. When looking at the response body, the IE response, is in fact an invalid character while in Chrome, it is the JSON payload.
I'm a little unsure where to even start looking into why IE wouldn't receive or parse the HTTP response correctly. Any ideas?
EDIT:
Making a cross-origin request from a Webpack Dev Server running on port 10000 to a local ASP.NET Core app running on 10001. When packaged for deployment, both the React App and the ASP.NET Core App run on 10000.
Headers between the two requests.
IE Request
IE Response
Chrome
Updated the endpoint to return an IActionResult and explicitly returning JSON. Same result. I've also realized it doesn't work in Edge either.
[Authorize]
[Route("/dashboard")]
public IActionResult Index()
{
return Json(
new { dashboard = _dashboard, authenticated = HttpContext.User.Identity.IsAuthenticated }
);
}
Without additional info I suspect the issue is related to ASP.Net's content negotiation and the fact your method return type is object. Don't use object, this is not Java :))
Before anything else, make sure fetch is sending an Accept: application/json header in IE.
I would also recommend for you to change the return type to IActionResult (or JSONResult if you want to force JSON) for your controller methods.

No headers available in xhr object when an UNAUTHORIZED error occurs - IE10

I have a CORS Ajax call to a web api. I have a message handler which throws an:
var msg = new HttpResponseMessage(HttpStatusCode.Unauthorized) { ReasonPhrase = "Oops!!!" };
throw new HttpResponseException(msg);
On the client I can't get no response headers, tried:
error: function (xhr, error) {
var result = xhr.getResponseHeader("Response");
but result is null and no other heades are available.
The Debugger shows correctly a 401!
Should I return the Unauthorized Exception differently from the server?
Update:
I forgot the add the Origin header to my HttpResponseException, in order to get the headers.
But in IE10 I don't get any headers, only error message
"error"
How can I know what happend, when using IE10?
Here is related question.
As I cannot get the Headers when returning a 401 response.
No instead I return NoContent StatusCode, which triggers the AJAX success eventhandler.
Now I have to check the response header "response" (which I manually add on the server side) in the success eventhandler, in order to make it work in IE 10:
Server:
var msg = new HttpResponseMessage(HttpStatusCode.NoContent) { ReasonPhrase = "UNAUTHORIZED" };
msg.Headers.Add("RESPONSE", "401");
AddCORSHeaders(msg.Headers, request);
return await Task.FromResult(msg);
Client:
error: function (jqXhr, error) {
var isAuth= jqXhr.getResponseHeader("Response");
Now I get a "response" header with value 401.
IF SOMEONE HAS A BETTER APPROACH, I'LL EXCEPT THE ANSWER !
In IE10 the ajax error eventhandler you get readyState=0 and status="".
In Chrome you get a 401 and readyState=4.

xhr sending requests to specific port?

I am very new to ajax development, I am trying to use xhr to get and post data,the problem is when I use port based requests?
here is my working code and not working codes
$.ajax({
url : "login.php",
type : "post",
data : {
userProfile : JSON.stringify(data)
},
success : handleDBResponse,
error : function(jqXHR, textStatus,errorThrown) {
console.log("The following error occured: "+ textStatus,errorThrown);
},
complete : function() {
// console.log("user authentication
// successful.")
}
});
this works good, but when I am using native xhr with url:port getting no response.
function reqListener () {
console.log(this.responseText);
};
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "http://www.domain.com:443/akorp.css", true);
oReq.send();
It's not working, I was debugged and I found request status is cancelled.
.htaccess file included
Access-Control-Allow-Origin:*
still I am getting the error
www.domain.com:443 not allowed by www.domain.com Access-Control-Allow-Origin etc..
what are the possible causes for this error and how to properly send request to port?
443 is the HTTPS port. Perhaps you should try an HTTPS URL instead of forcing the port.
I'm not sure I want to know why you're pulling a CSS file from somebody else's serer with xhr.

ajax from Chrome-Extension processed, but receive responseText="" and status=0

I am writing a google-chrome extension, that needs to make ajax requests to a server, send some data, and receive some data back. My server is Tomcat 6.0, running on localhost.
I am able to receive all the data on the server side, do all the processing I need, and send a response back to the extension,
but the status i get in the callback is 0, and responseText="".
my guess is that the problem lies either in the server - returning a response to a request originating from chrome-extension://... url, or in the extension - receiving a response from localhost:8080.
I've set the necessary permissions of course, and I tried setting content-type of the response to "text/xml", "text/html" and "text/plain" - it makes no difference.
I've tried using ajax both with XMLHttpRequest and JQuery - same problem with both.
I've found these issues, but they don't seem to solve my problem:
1. http://www.plee.me/blog/2009/08/ajax-with-chrome-empty-responsetext/
2. http://bugs.jquery.com/ticket/7653
here's my code:
bg.js (background page)
function saveText(data) {
var requrl = serverUrl + addTextUrl;
var params = json2urlParams(data);
jQuery.ajax({
type : "POST",
url : requrl,
data : params,
success : function (data, textStatus, XMLHttpRequest) {
console.log("Data Saved: " + msg);
}
});
// var xhr = new XMLHttpRequest();
// xhr.open("POST", requrl, true);
// xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// xhr.onreadystatechange = function (progress) {
// if (xhr.readyState == 4) {
// console.log("Data Saved: " + this.response);
// }
// };
// xhr.send(params);
}
addContentServlet.java: (server side)
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ErrorCodes error = addContent(request, response);
response.setContentType("text/plain");
//response.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
//response.setIntHeader("errorCode", error.ordinal());
response.getWriter().write(error.toString());
response.setIntHeader("errorcode", error.ordinal());
if(error == ErrorCodes.SUCCESS){
response.setStatus(error.toHttpErrorCode());
response.flushBuffer();
}
else{
response.sendError(error.toHttpErrorCode(), error.toString());
}
}
EDIT:
I've noticed in the chrome console of the background page that for every ajax that returns to the extension i get a
XMLHttpRequest cannot load
http:// localhost:8080/stp_poc/MyServlet.
Origin
chrome-extension://fmmolofppekcdickmdcjflhkbmpdomba
is not allowed by
Access-Control-Allow-Origin.
I tried loosing bg.js and puting all the code in the main page instead - to no avail.
how come XMLHttpRequest agrees to send the request, but not receive it back??
Maybe a server-configuration problem? I'm a newb, so maybe i missed something basic, like a header in the response
EDIT
I've finally pinned the problem:
I shouldn't have included the port number in my permission. Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]
everything seems to works fine now.
The problem was that I shouldn't have included the port number in my permission.
Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]

Resources