getJSON not updating div containers with new values [duplicate] - javascript

I have a machine on my local lan (machineA) that has two web servers. The first is the in-built one in XBMC (on port 8080) and displays our library. The second server is a CherryPy python script (port 8081) that I am using to trigger a file conversion on demand. The file conversion is triggered by a AJAX POST request from the page served from the XBMC server.
Goto http://machineA:8080 which displays library
Library is displayed
User clicks on 'convert' link which issues the following command -
jQuery Ajax Request
$.post('http://machineA:8081', {file_url: 'asfd'}, function(d){console.log(d)})
The browser issues a HTTP OPTIONS request with the following headers;
Request Header - OPTIONS
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://machineA:8080
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
The server responds with the following;
Response Header - OPTIONS (STATUS = 200 OK)
Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:40:29 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1
The conversation then stops. The browser, should in theory, issue a POST request as the server responded with the correct (?) CORS headers (Access-Control-Allow-Origin: *)
For troubleshooting, I have also issued the same $.post command from http://jquery.com. This is where I am stumped, from jquery.com, the post request works, a OPTIONS request is sent following by a POST. The headers from this transaction are below;
Request Header - OPTIONS
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://jquery.com
Access-Control-Request-Method: POST
Response Header - OPTIONS (STATUS = 200 OK)
Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1
Request Header - POST
Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://jquery.com/
Content-Length: 12
Origin: http://jquery.com
Pragma: no-cache
Cache-Control: no-cache
Response Header - POST (STATUS = 200 OK)
Content-Length: 32
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: application/json
I can't work out why the same request would work from one site, but not the other. I am hoping someone might be able to point out what I am missing. Thanks for your help!

I finally stumbled upon this link "A CORS POST request works from plain javascript, but why not with jQuery?" that notes that jQuery 1.5.1 adds the
Access-Control-Request-Headers: x-requested-with
header to all CORS requests. jQuery 1.5.2 does not do this. Also, according to the same question, setting a server response header of
Access-Control-Allow-Headers: *
does not allow the response to continue. You need to ensure the response header specifically includes the required headers. ie:
Access-Control-Allow-Headers: x-requested-with

REQUEST:
$.ajax({
url: "http://localhost:8079/students/add/",
type: "POST",
crossDomain: true,
data: JSON.stringify(somejson),
dataType: "json",
success: function (response) {
var resp = JSON.parse(response)
alert(resp.status);
},
error: function (xhr, status) {
alert("error");
}
});
RESPONSE:
response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")
return response

I solved my own problem when using google distance matrix API by setting my request header with Jquery ajax. take a look below.
var settings = {
'cache': false,
'dataType': "jsonp",
"async": true,
"crossDomain": true,
"url": "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=place_id:"+me.originPlaceId+"&destinations=place_id:"+me.destinationPlaceId+"&region=ng&units=metric&key=mykey",
"method": "GET",
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
Note what i added at the settings
**
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*"
}
**
I hope this helps.

Took me some time to find the solution.
In case your server response correctly and the request is the problem, you should add withCredentials: true to the xhrFields in the request:
$.ajax({
url: url,
type: method,
// This is the important part
xhrFields: {
withCredentials: true
},
// This is the important part
data: data,
success: function (response) {
// handle the response
},
error: function (xhr, status) {
// handle errors
}
});
Note: jQuery >= 1.5.1 is required

Well I struggled with this issue for a couple of weeks.
The easiest, most compliant and non hacky way to do this is to probably use a provider JavaScript API which does not make browser based calls and can handle Cross Origin requests.
E.g. Facebook JavaScript API and Google JS API.
In case your API provider is not current and does not support Cross Origin Resource Origin '*' header in its response and does not have a JS api (Yes I am talking about you Yahoo ),you are struck with one of three options-
Using jsonp in your requests which adds a callback function to your URL where you can handle your response.
Caveat this will change the request URL so your API server must be equipped to handle the ?callback= at the end of the URL.
Send the request to your API server which is controller by you and is either in the same domain as the client or has Cross Origin Resource Sharing enabled from where you can proxy the request to the 3rd party API server.
Probably most useful in cases where you are making OAuth requests and need to handle user interaction Haha! window.open('url',"newwindowname",'_blank', 'toolbar=0,location=0,menubar=0')

This is a summary of what worked for me:
Define a new function (wrapped $.ajax to simplify):
jQuery.postCORS = function(url, data, func) {
if(func == undefined) func = function(){};
return $.ajax({
type: 'POST',
url: url,
data: data,
dataType: 'json',
contentType: 'application/x-www-form-urlencoded',
xhrFields: { withCredentials: true },
success: function(res) { func(res) },
error: function() {
func({})
}
});
}
Usage:
$.postCORS("https://example.com/service.json",{ x : 1 },function(obj){
if(obj.ok) {
...
}
});
Also works with .done,.fail,etc:
$.postCORS("https://example.com/service.json",{ x : 1 }).done(function(obj){
if(obj.ok) {
...
}
}).fail(function(){
alert("Error!");
});
Server side (in this case where example.com is hosted), set these headers (added some sample code in PHP):
header('Access-Control-Allow-Origin: https://not-example.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 604800');
header("Content-type: application/json");
$array = array("ok" => $_POST["x"]);
echo json_encode($array);
This is the only way I know to truly POST cross-domain from JS.
JSONP converts the POST into GET which may display sensitive information at server logs.

Using this in combination with Laravel solved my problem. Just add this header to your jquery request Access-Control-Request-Headers: x-requested-with and make sure that your server side response has this header set Access-Control-Allow-Headers: *.

I had the exact same issue where jquery ajax only gave me cors issues on post requests where get requests worked fine - I tired everything above with no results. I had the correct headers in my server etc. Changing over to use XMLHTTPRequest instead of jquery fixed my issue immediately. No matter which version of jquery I used it didn't fix it. Fetch also works without issues if you don't need backward browser compatibility.
var xhr = new XMLHttpRequest()
xhr.open('POST', 'https://mywebsite.com', true)
xhr.withCredentials = true
xhr.onreadystatechange = function() {
if (xhr.readyState === 2) {// do something}
}
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.send(json)
Hopefully this helps anyone else with the same issues.

This function will asynchronously get an HTTP status reply from a CORS-enabled page. Only a page with the proper headers returns a 200 status if accessed via XMLHttpRequest -- whether GET or POST is used. Nothing can be done on the client side to get around this except possibly using JSONP if you just need a json object.
The following can be modified to get the data held in the xmlHttpRequestObject object:
function checkCorsSource(source) {
var xmlHttpRequestObject;
if (window.XMLHttpRequest) {
xmlHttpRequestObject = new XMLHttpRequest();
if (xmlHttpRequestObject != null) {
var sUrl = "";
if (source == "google") {
var sUrl = "https://www.google.com";
} else {
var sUrl = "https://httpbin.org/get";
}
document.getElementById("txt1").innerHTML = "Request Sent...";
xmlHttpRequestObject.open("GET", sUrl, true);
xmlHttpRequestObject.onreadystatechange = function() {
if (xmlHttpRequestObject.readyState == 4 && xmlHttpRequestObject.status == 200) {
document.getElementById("txt1").innerHTML = "200 Response received!";
} else {
document.getElementById("txt1").innerHTML = "200 Response failed!";
}
}
xmlHttpRequestObject.send();
} else {
window.alert("Error creating XmlHttpRequest object. Client is not CORS enabled");
}
}
}
<html>
<head>
<title>Check if page is cors</title>
</head>
<body>
<p>A CORS-enabled source has one of the following HTTP headers:</p>
<ul>
<li>Access-Control-Allow-Headers: *</li>
<li>Access-Control-Allow-Headers: x-requested-with</li>
</ul>
<p>Click a button to see if the page allows CORS</p>
<form name="form1" action="" method="get">
<input type="button" name="btn1" value="Check Google Page" onClick="checkCorsSource('google')">
<input type="button" name="btn1" value="Check Cors Page" onClick="checkCorsSource('cors')">
</form>
<p id="txt1" />
</body>
</html>

If for some reasons while trying to add headers or set control policy you're still getting nowhere you may consider using apache ProxyPass…
For example in one <VirtualHost> that uses SSL add the two following directives:
SSLProxyEngine On
ProxyPass /oauth https://remote.tld/oauth
Make sure the following apache modules are loaded (load them using a2enmod):
proxy
proxy_connect
proxy_http
Obviously you'll have to change your AJAX requests url in order to use the apache proxy…

This is a little late to the party, but I have been struggling with this for a couple of days. It is possible and none of the answers I found here have worked. It's deceptively simple.
Here's the .ajax call:
<!DOCTYPE HTML>
<html>
<head>
<body>
<title>Javascript Test</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
$(document).domain = 'XXX.com';
$(document).ready(function () {
$.ajax({
xhrFields: {cors: false},
type: "GET",
url: "http://XXXX.com/test.php?email='steve#XXX.com'",
success: function (data) {
alert(data);
},
error: function (x, y, z) {
alert(x.responseText + " :EEE: " + x.status);
}
});
});
</script>
</body>
</html>
Here's the php on the server side:
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
header('Origin: xxx.com');
header('Access-Control-Allow-Origin:*');
$servername = "sqlxxx";
$username = "xxxx";
$password = "sss";
$conn = new mysqli($servername, $username, $password);
if ($conn->connect_error) {
die( "Connection failed: " . $conn->connect_error);
}
$sql = "SELECT email, status, userdata FROM msi.usersLive";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo $row["email"] . ":" . $row["status"] . ":" . $row["userdata"] . "<br>";
}
} else {
echo "{ }";
}
$conn->close();
?>
</body>

Related

Google Charts - DataTable Issue with API Request and jQuery

I am struggling mightily with what should be a simple AJAX call to an API that renders back DataTable formatted data (Google Visualization API Reference) for insertion into a Google Chart. The data is successfully received via the AJAX call and I can alert the response to the browser with no issue. However, when I pass in the same exact variable chartData - I'm met with an error in the console:
Uncaught (in promise) SyntaxError: Unexpected token c in JSON at position 1
at JSON.parse ()
I've placed the code I'm using below; any assistance would be significantly appreciated.
FRONT END [charts-testing.php]
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var chartData = $.ajax({
url: "includes/processing/process_chart_data.php",
async: false,
}).responseText;
alert(chartData);
var data = new google.visualization.DataTable(chartData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
BACK END [process-chart-data.php]
<?php
include_once '../classes/clsAPI.php';
$objAPI = new clsAPI();
$api = [redacted]
$chartData = $objAPI->getDataTable($api);
header('Content-Type: text/plain');
echo $chartData;
?>
RESPONSE FROM process-chart-data.php
{cols:[{id:'AgeRange',label:'Age Range',type:'string'},{id:'MemberCount',label:'Member Count',type:'number'}],rows:[{c:[{v:'18-34'},{v:200}]},{c:[{v:'35-44'},{v:200}]},{c:[{v:'45-54'},{v:400}]},{c:[{v:'55-64'},{v:500}]},{c:[{v:'65-74'},{v:600}]}]}
REQUEST HEADERS
GET /includes/processing/process_chart_data.php HTTP/1.1
Host: local.site.com
Connection: keep-alive
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36
Referer: http://local.site.com/charts-testing.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,fr;q=0.8
RESPONSE HEADERS
HTTP/1.1 200 OK
Date: Thu, 13 Feb 2020 07:08:12 GMT
Server: Apache/2.2.34 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.2.10 mod_ssl/2.2.34 OpenSSL/1.0.2o DAV/2 mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_perl/2.0.9 Perl/v5.24.0
X-Powered-By: PHP/7.2.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 247
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/plain;charset=UTF-8
It should also be noted that by replacing chartData with the exact response from the API (no formatting), it renders the chart without error.
EDIT
To illustrate the response from the API call working if manually injected into the Visualization call, see below. This successfully displays the chart and is identical to the value of var chartData:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var chartData = $.ajax({
url: "includes/processing/process_chart_data.php",
async: false,
}).responseText;
alert(chartData);
var data = new google.visualization.DataTable({cols:[{id:"AgeRange",label:"Age Range",type:"string"},{id:"MemberCount",label:"Member Count",type:"number"}],rows:[{c:[{v:"18-34"},{v:200}]},{c:[{v:"35-44"},{v:200}]},{c:[{v:"45-54"},{v:400}]},{c:[{v:"55-64"},{v:500}]},{c:[{v:"65-74"},{v:600}]}]});
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
it appears that Google Visualization API doing json.parse on your data response from server so
$objAPI->getDataTable should output your JSON object like this
instead of using 'cols' for strings and object elements name use "cols"
cols: [{id: 'A', label: 'NEW A', type: 'string'}]
use this
"cols": [{"id":"A", "label": "NEW A", "type": "string"}]
also why using async:false
take a look at this
you should use async then call on-success success:function(data){/*call chart foramtting*/}
async (default: true) Type: Boolean By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active. As of jQuery 1.8,
the use of async: false with jqXHR ($.Deferred) is deprecated; you
must use the success/error/complete callback options instead of the
corresponding methods of the jqXHR object such as jqXHR.done().
or
$.get('includes/processing/process_chart_data.php', function (chartData) {
var data = new google.visualization.DataTable(chartData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});});

Postman GET request works but not Ajax CORS

I am trying to make an AJAX request to get information of a restAPI.
If I test it with POSTMAN, it works and with Putty too with this code selecting RAW, but not with AJAX due to CORS issues.
This is the code that works on Putty (it returns JSON data):
GET /api/slot/0/io/do HTTP/1.1\r\n
Host: 172.25.0.208\r\n
Content-Type: application/json\r\n
Accept: vdn.dac.v1\r\n
\r\n
This is the jQuery AJAX code:
//Build GET Request URL
var url = "//" + ipDevice + "/api/slot/" + slot + "/io/do";
jQuery.support.cors = true;
//GET Request with HTTP header info
$.ajax({
"url": url,
"method": "GET",
"headers": {
"Accept": "vdn.dac.v1",
"Content-type": "application/json"
},
"success": function (response) {
getPowerStatusSuccess(response);
},
"error": function (response) {
getPowerStatusFail(response);
}
});
The error I got on browser console (Firefox) is:
Your api needs to return a cors header ~allow-origin set to * or a whitelist of domains.
access-control-allow-origin: *

Angularjs Rest endpoint with username password

I am trying to write a Single Page App (SPA) based on AngularJS. The app should connect to a webserver that provides a RestFul services, but each end point requires username and password along with other parameters. Since I am a beginner in this area, before moving towards the actual development, I tried PostMan/Advanced Rest Client chrome extensions to verify the basic connections. A sample request preview :
POST /servicesNS/admin/search/search/jobs/export HTTP/1.1
Host: localhost:8089
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
search=search+error+|+table+host&output_data=xml&username=admin&password=unity3d
This is actually equivalent to the cURL command:
curl -k -u admin:unity3d --data-urlencode search="search error | table host" -d "output_mode=xml" https://localhost:8089/servicesNS/admin/search/search/jobs/result
After getting successful results in above mentioned ways, I am now looking for equivalent way of doing it in AngularJS.
var app = angular.module('TabsApp', []);
app.controller('TabsCtrl', function ($scope, $http)
{
login = function () {
$scope.userName ="admin";
$scope.password ="unity3d"
$http({
method :"POST",
url:"https://localhost:8089/servicesNS/admin/search/search/jobs/export",
data: { "username" : "admin" , "password": "unity3d", "search" : "search error"},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
console.log('status',status);
console.log('data',status);
console.log('headers',status);
});
}
});
This gives me error 401 Unauthorized, the headers of the response:
> Remote Address:127.0.0.1:8089 Request
> URL:https://localhost:8089/servicesNS/admin/search/search/jobs/export
> Request Method:POST Status Code:401 Unauthorized Request Headersview
> source Accept:application/json, text/plain, */* Accept-Encoding:gzip,
> deflate Accept-Language:en-US,en;q=0.8 Connection:keep-alive
> Content-Length:65 Content-Type:application/x-www-form-urlencoded
> Host:localhost:8089 Origin:http://localhost:63342
> Referer:http://localhost:63342/UI/UI1.html User-Agent:Mozilla/5.0
> (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
> Chrome/39.0.2171.71 Safari/537.36 Form Dataview sourceview URL encoded
> {"username":"admin","password":"unity3d","search":"search error"}:
> Response Headersview source Access-Control-Allow-Credentials:true
> Access-Control-Allow-Headers:Authorization
> Access-Control-Allow-Methods:GET,POST,PUT,DELETE,HEAD,OPTIONS
> Access-Control-Allow-Origin:* Cache-Control:private
> Connection:Keep-Alive Content-Length:130 Content-Type:text/xml;
> charset=UTF-8 Date:Sat, 29 Nov 2014 19:53:59 GMT Server:Splunkd
> Vary:Cookie, Authorization WWW-Authenticate:Basic realm="/splunk"
> X-Content-Type-Options:nosniff X-Frame-Options:SAMEORIGIN
And the output is :
<?xml version="1.0" encoding="UTF-8"?> <response> <messages>
<msg type="ERROR">Unauthorized</msg> </messages> </response>
Any idea what is going wrong?
If you are sending response in the format of 'application/x-www-form-urlencoded' the actual data format should be the same.
What you are sending currently is a JSON object. You would need to use $http tranformer to tranform the request: Something in line of
transformRequest: function (data) {
var postData = [];
for (var prop in data)
postData.push(encodeURIComponent(prop) + "=" + encodeURIComponent(data[prop]));
return postData.join("&");
},
See a working fiddle here http://jsfiddle.net/cmyworld/doLhmgL6/

how to monitor progress response of ajax request with jquery

How to monitor progress response of ajax request with jquery
I call an API that performs several lookups on the server. One call can result in 5-10 lookups. Each time a lookup is completed, the API appends a string to the GET response. When all lookups are completed, the connection is closed.
I'd like to have a callback that is triggered upon progress and preferrably find a a way of parsing the servers progress response (accessing the data) upon each completed lookup.
My problem is that the progress callback is never called.
This is my code so far. I tried to patch the xmlHttpRequest Object and extend jquery's ajax method.
(function addXhrProgressEvent($) {
var originalXhr = $.ajaxSettings.xhr;
$.ajaxSetup({
xhr : function() {
var req = originalXhr(), that = this;
if (req) {
if ( typeof req.addEventListener == "function" && that.progress !== undefined) {
req.addEventListener("progress", function(evt) {
that.progress(evt);
}, false);
}
if ( typeof req.upload == "object" && that.progressUpload !== undefined) {
req.upload.addEventListener("progress", function(evt) {
that.progressUpload(evt);
}, false);
}
}
return req;
}
});
})(jQuery);
$('#update').on('click', function(e) {
e.preventDefault();
var json = $.ajax({
headers : {
'Authorization' : "Basic " + btoa("abced:becd")
},
url : "http://123.123.123.123:5487/api/v1/check/" + $(this).attr('data-key'),
type : "GET",
crossDomain : true,
dataType : "text",
async : false,
progress : function(evt) {
/*this does not fire*/
alert('callback fired!');
/*this does not fire*/
if (evt.lengthComputable) {
console.log("Loaded " + parseInt((evt.loaded / evt.total * 100), 10) + "%");
} else {
console.log("Length not computable.");
}
},
success : function(data, textStatus, jqXHR) {
},
error : function(jqXHR, textStatus, errorThrown) {
}
});
});
});
This is the server's response
['task 1 completed']
\n
\n
\n
['task 3 completed']
\n
\n
\n
['task 4 completed']
...
Request Header
Accept text/plain, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language de,en-US;q=0.7,en;q=0.3
Authorization Basic 12123456020600662232112311==
Host 123.123.123.123:1234
Origin http://123.123.123.132
Referer http://123.123.123.123/index.php/db/SSRelaunch
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Response Header
Access-Control-Allow-Head... X-Requested-With, Content-Type, Authorization
Access-Control-Allow-Meth... GET,POST,PUT,OPTIONS
Access-Control-Allow-Orig... *
Content-Length 100000
Content-Type text/plain
Date Mon, 28 Jul 2014 18:06:27 GMT
Server BaseHTTP/0.3 Python/2.7.3
There is not a progress function built into the jQuery ajax API, but you can add an event listener to handle the information.
Check out the answer for this question on how to do it:
What is the cleanest way to get the progress of JQuery ajax request?

Import page in Mediawiki

I create a script ( js ) to import a page in my mediawiki.
I have a "incorrect token". What's wrong ?
var xhttp = new ActiveXObject("Microsoft.XmlHttp");
xmlHttp2.open("POST", url, false);
xmlHttp2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp2.send("action=query&prop=info&intoken=import&titles=Test2");
var result2 = xmlHttp2.responseText;
var resultTokenImport = extractTokenImport(result2);
//return me 'dsa7u6ds6u7asd76das67sad+\' ( more or less :D )
xmlHttp2.open("POST", url, false);
xmlHttp2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp2.send("action=import&format=xml&xml="+dump+"&token="+resultTokenImport);
Well, the problem is that 'import' need 'another' type of Token.
now, my problem is:
xmlHttp2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
give me an error "nofile"
and for this code :
xmlHttp2.setRequestHeader("Content-Type", "multipart/form-data");
it send me a:
Missing boundary in multipart/form-data POST data in Unknown on line 0
If it says "no file" it is expecting a file in a POST body. You can easily POST using FormData.
To quote from /api.php
xml - Uploaded XML file
Must be posted as a file upload using multipart/form-data
Example
Here is what is working for me. For simplicity, the following code is reading from a textarea and makes use of MediaWiki's JavaScript includes:
var apiUrl = mw.util.wikiScript( 'api' );
var onreadystatechange = function() {
if ( 4 !== this.readyState ) return;
if ( 200 === this.status ) {
console.log( this.response );
}
};
function continueWithToken ( token ) {
var fd = new FormData();
var xhr = new XMLHttpRequest();
// First argument is an array!
var bXml = new Blob( [$( 'textarea' ).val()], {
type: 'text/xml'
} );
fd.append( 'format', 'json' );
fd.append( 'action', 'import' );
// Third parameter is not required but
// You're likely on the safe side using it
fd.append( 'xml', bXml, 'file.xml' );
fd.append( 'token', token );
xhr.onreadystatechange = onreadystatechange;
xhr.open( 'POST', apiUrl );
xhr.send( fd );
}
$.get( apiUrl, {
format: 'json',
type: 'import',
action: 'tokens'
} ).done( function(r) {
var token = r.tokens.importtoken;
continueWithToken( token );
} );
This is just a minimal implementation. Do not forget error-handling. If you have the exports as files for upload and want to make it working in older browsers not sufficiently supporting Blobs and FormData, just build a form! The form's target could be an iframe so you can read the response from it without exposing the blank API result page to your users.
Expected response
{"import":[{"ns":0,"title":"Main Page2","revisions":1}]}
Complete request
The request that is composed by the client and sent to the server for reference. Note the file's in a POST body.
POST http://localhost/api.php HTTP/1.1
Host: localhost
User-Agent: <ua string>
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/index.php?title=Special:Export&action=submit
Content-Length: 3231
Content-Type: multipart/form-data; boundary=---------------------768648126486
Cookie: <redacted>; mwdbUserID=1; mwdbUserName=Rillke
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
-----------------------768648126486
Content-Disposition: form-data; name="format"
json
-----------------------768648126486
Content-Disposition: form-data; name="action"
import
-----------------------768648126486
Content-Disposition: form-data; name="xml"; filename="file.xml"
Content-Type: text/xml
<mediawiki ...schemas... version="0.8" xml:lang="en">
<siteinfo>
<sitename>Sample Wiki</sitename>
<!-- .... -->
</mediawiki>
-----------------------768648126486
Content-Disposition: form-data; name="token"
XX39e9fd22a9de7675c71eadcfd2XXXX+\
-----------------------768648126486--
As for the "Missing boundary in multipart/form-data POST data" error, this is because you send it url-encoded but claim it would be multipart/form-data. MediaWiki is looking for a boundary in the header but cannot find it.

Categories