I call a page using AJAX, requesting a search for something. But the response text is always empty, although the ready state is 4.
function process() {
var requestPage = "http://some.page/search.php";
var xmlHTTP;
var searchString = "test";
if (window.XMLHttpRequest) {
xmlHTTP = new XMLHttpRequest();
} else {
xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
}
var results;
xmlHTTP.open("GET", requestPage + "?search=" + searchString, true);
xmlHTTP.send();
xmlHTTP.onreadystatechange = function() {
results = xmlHTTP.responseText;
alert("r: " + results + " rs: " + xmlHTTP.readyState + " st: " + xmlHTTP.status);
}
}
The results I get from this are
r: rs: 2 st: 0
r: rs: 4 st: 0
So, the request is done successfully, but the HTTP status isn't 200. But: I tracked the request using WireShark and the result package of the request shows as status 200 and even contains the complete result of the request, see below:
7014 190.663287 some.page local.pc HTTP HTTP/1.1 200 OK (text/html)
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=xxx; Path=/xxx
Content-Type: text/html;charset=iso-8859-1
Content-Length: 3108
Date: Tue, 19 Apr 2011 13:05:41 GMT
<html>
<head>
<title>Search</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="white">
...
So; why don't I get the status 200 on my AJAX request when it obviously succeded?
So your problem is that you are requesting a page with a different port.
The same origin policy says that the protocol, port and host should be the same.
See
http://en.wikipedia.org/wiki/Same_origin_policy and https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
Related
I am doing post request to an api !
string url = "http://xxx.xxx.xx.xx/api/QMn/Create";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
// client.Headers.ContentType = new MediaTypeHeaderValue("application/json");
StringContent content = new StringContent(JsonConvert.SerializeObject(DataToSave), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
the Api recieving request is this :
public void Create([FromBody] IEnumerable<QMSRejection> DataToSave)
{
try
{
_QMSRejection.Create(DataToSave);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
I am receiving this error I am not able to understand why ?
{StatusCode: 204, ReasonPhrase: 'No Content',
Version: 1.1, Content: System.Net.Http.StreamContent,
Headers: { Cache-Control: no-cache
Date: Fri, 28 Aug 2020 06:18:43 GMT Pragma: no-cache
Server: Microsoft-IIS/10.0 X-Android-Received-Millis: 1598595526870
X-Android-Response-Source: NETWORK 204 X-Android-Selected-Protocol: http/1.1
X-Android-Sent-Millis: 1598595526011
X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Expires: -1 }}
Do I have to pass headers but I only require to pass body !
I solved the issue the error was from API Side and not client side ! There were validations in the API that was causing it to give such errors !
I was testing a tool that fires some asynchronous ajax requests. The response of one request can abort another one. This works great as far as I have tested this (Chrome, Firefox) but Edge doesn't like aborting! As soon as the XmlHttpRequest is blocked, Edge throws a fail - which I wish not to happen.
This is the code (that gets aborted by another snippet):
xhr = $.ajax("my-url.php")
.done(function(json) {
var data = $.parseJSON(json);
if (data.data) {
// Yay data!
} else {
// Ahw no data or empty data
}
})
.fail(function(jqXHR, textStatus, error) {
// This is triggered by Edge, `error` is "abort"
var string = "An error occurred: " + error + ".";
alert(string);
})
.always(function() {
done = true;
});
So, the result is an alert An error occurred: abort. Question one: why is Edge doing this? Does it handle XHR in a different way than other browsers? What is the standard? Secondly, how do I make sure I do not show this message? Can I simply do something like this in fail(), or isn't that a pretty way of going about this:
if (error != 'abort') {
// Do stuff, only when error isn't abort
}
It seems that I found what happens.
This is my code (copied from yours):
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
'use strict';
var xhr, done;
function getResp() {
if (!done && xhr && xhr.readyState !== 4)
xhr.abort();
done = false;
xhr = $.ajax("json.php",{method:'GET'})
// you didn't include method so method is 'GET'
// when I change it to 'POST' Edge honors xhr.abort()
.done(function (json) {
console.log(json);
var data = $.parseJSON(json);
if (data.data) {
// Yay data!
} else {
// Ahw no data or empty data
}
})
.fail(function (jqXHR, textStatus, error) {
// This is triggered by Edge, `error` is "abort"
var string = "An error occurred: " + error + ".";
//alert(string);
console.log(string);
})
.always(function () {
done = true;
});
}
</script>
</head>
<body>
<input type="button" onclick="getResp()" value="run" />
</body>
</html>
and my php:
<?php
usleep(10000000); //10 seconds
echo '{"name":"test","qty":10,"curr":"'.date('h:i:s').'"}';
?>
General answer: Edge caches xhr GET response and returns data immediately. FF sends request to the server. It makes all difference.
POST requests aren't cached and xhr.abort() produces expected result in all browsers.
Is it acceptable answer?
I am using dataUrl to populate my dropdown in form edit of jqGrid, but i am not getting any response from server. what am i missing? fiddler shows no error
editoptions: {
dataUrl: "CurrencySetting.aspx/GetDet",
buildSelect: function (response) {
alert(response.responseText);
var data = typeof response === "string" ?
$.parseJSON(response.responseText) : response;
s = "<select>";
s += '<option value="0">------</option>';
$.each(data, function () {
s += '<option value="1">' + this.CurrencyCd +
'</option>';
});
return s + "</select>";
}
}
server code:
public static string GetDet()
{
SysDataContext db = new SysDataContext();
var query = (from SC in db.SysCurrencySettings
select new
{
SC.CurrencyCd
}).ToList();
return JsonConvert.SerializeObject(query);
}
HTTP response
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Thu, 22 Oct 2015 11:10:23 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 15497
Connection: Close
Recently I found very strange behavior of IE8/9 when sending XHR data. I'd like to ask you if you have ever seen such behavior? Is it IE bug? How can I protect my server from "empty" request generated by IE? Here are more details:
I found out that when your page tries to send XHR data and JavaScript freezes or lags browser, IE lags sending POST data to server. To make it clear, here are steps to reproduce:
Create simple server which dumps POSTs received. I've used Node.JS for tests. You can find corresponding codes at the bottom of the post.
Open localhost:8080 in IE, open debug window and start debuging scripts with breakpoint set in line 51 of file localhost:8080
Hit Send by JQuery. You should have your javascript waiting on the breakpoint and server logged message:
--------------------------------------
14:04:19
REQUEST: /
HTTP HEADER:
accept = text/html, application/xhtml+xml, */*
accept-language = pl-PL
user-agent = Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
accept-encoding = gzip, deflate
host = localhost:8080
connection = Keep-Alive
--------------------------------------
14:04:35
REQUEST: /test
HTTP HEADER:
accept = */*
content-type = application/json
x-requested-with = XMLHttpRequest
referer = http://localhost:8080/
accept-language = pl
accept-encoding = gzip, deflate
user-agent = Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
host = localhost:8080
content-length = 24
connection = Keep-Alive
cache-control = no-cache
When you release JavaScript from the breakpoint server reports incoming data by new line:
POST: {"data1":10,"data2":123}
I've done the same test on Opera 12.15 and Chrome 27.0.1453.94 m and, as expected, POST data are sent immediately.
-- source codes --
Code for node.js server:
var http = require('http');
var qs = require('querystring');
var fs = require('fs');
http.createServer(function (req, res) {
console.log('--------------------------------------');
console.log(new Date().toLocaleTimeString());
console.log('REQUEST: ' + req.url);
console.log('HTTP HEADER: ');
for (var header in req.headers) {
console.log(' ' + header + ' = ' + req.headers[header]);
}
switch (req.method) {
case 'POST':
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function() {
console.log('POST: ' + body);
});
res.writeHead(200, {'Content-type': 'application/json'});
res.end(JSON.stringify({ succeeded: true, value: 'Hello world!' }));
break;
case 'GET':
fs.readFile('./servertest.html', function (err, data) {
if (err) {
throw err;
}
res.writeHeader(200, {'Content-type': 'text/html'});
res.end(data);
});
break;
}
}).listen(8080, 'localhost');
console.log('listening on localhost:8080');
Code for servertest.html:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<button onclick="send()">Send by JQuery</button>
<button onclick="sendXHR()">Send by XHR</button>
</body>
<script type="text/javascript">
var _xhr;
function sendXHR() {
_xhr = new XMLHttpRequest();
new XHRStateChangeListener();
var url = '/testXHR';
var method = 'POST';
_xhr.open(method, url);
_xhr.setRequestHeader("Content-Type", "application/json");
_xhr.send(JSON.stringify({test: 'this is a test', aoawiejf:23423}));
}
function XHRStateChangeListener() {
callback = function() {
var msg;
if (_xhr.readyState == 4 && /200|304/.test(_xhr.status)) {
alert('ready: ' + _xhr.responseText);
}
};
_xhr.onreadystatechange = callback;
}
function send() {
$.ajax({
url: '/test',
type: 'POST',
data: JSON.stringify({data1: 10, data2: 123}),
contentType: 'application/json',
error: function(xhr, status, err) {
alert('Error: ' + err + '\nStatus: ' + status);
},
success: function (data) {
alert('succeeded! data: ' + data);
}
});
}
</script>
</html>
You are using sync-mode, right is async-mode:
replace
_xhr.open(method, url);
by
_xhr.open(method, url, true);//Async mode
Note: Remember "onreadystatechange" is only for async-mode
the problem may also be in this function (just a guess):
JSON.stringify
try sending empty data, ie: data:""
Can somebody help me how to post an array of type long to a WebApi.
I think I have to use PostAsync from HttpClient, but I am not sure how to put array to HttpContent.
This is my controller.
[HttpPost]
[Authorize]
public void UpdateBatchesToReadyToShip(long[] batchIds)
{
// process request
}
And this is how I am trying to consume API
var buffer = Encoding.ASCII.GetBytes("username:password");
var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(buffer));
client.DefaultRequestHeaders.Authorization = authHeader;
var arr = new long[3];
arr[0] = 10;
arr[1] = 12;
arr[2] = 13;
HttpContent content = new StringContent(string.Join(",", from i in arr select i.ToString()));
var task = client.PostAsync("https://<uri>/api/orderprocessing/UpdateBatchesToReadyToShip",content:content);
if (task.Result.StatusCode == HttpStatusCode.Unauthorized)
{
Console.WriteLine("wrong credentials");
}
else
{
//task.Result.EnsureSuccessStatusCode();
HttpResponseMessage message = task.Result;
if (message.IsSuccessStatusCode)
{
var details = message.Content.ReadAsStringAsync().Result;
Console.Write(details);
}
}
And I am getting this exception
{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
Cache-Control: no-cache
Date: Fri, 09 Nov 2012 12:37:44 GMT
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 1060
Content-Type: application/json; charset=utf-8
Expires: -1
}}
Instead of using StringContent, you can use ObjectContent:
var content = new ObjectContent<long[]>(arr, new JsonMediaTypeFormatter());
var task = client.PostAsync(
"https://<uri>/api/orderprocessing/UpdateBatchesToReadyToShip",
content:content);