I am trying to upload images and couple of form elements to a MVC Controller. The problem here isn't the model not being populated, because it works with application/x-www-form-urlencoded but seems to have trouble with multipart/form-data. The core of the problem is, that Request.Form is not being populated...
Converting Form to FormData:
function frmValuesAsFormData(submittedForm) {
return new FormData(submittedForm);
}
AJAX Function (asFormData is passed in as True in this case and method is POST and dataType is JSON):
function executeAJAX(method, url, data, asFormData, silent, callbackFunc, receiveFunc, dataType, targetDiv, appendToExistingContent, uid) {
var cType = "application/x-www-form-urlencoded";
var processData = true;
if (asFormData) {
cType = "multipart/form-data";
processData = false;
}
$.ajax({
method: method,
url: url,
data: data,
contentType: cType,
cache: false,
dataType: dataType,
processData: processData,
success: function (d, t, j) {
// Do something with result from controller...
}
});
}
POST Headers (From FireBug)
Accept application/json, text/javascript, /; q=0.01
Accept-Encoding gzip, deflate Accept-Language en-GB,en;q=0.5
Content-Length 936 Content-Type multipart/form-data Cookie
ASP.NET_SessionId=mzppxvimv03qb0smtyrgdw3z Host localhost:64727
Referer http://localhost:64727/Home/Contact User-Agent Mozilla/5.0
(Windows NT 10.0; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0
X-Requested-With XMLHttpRequest
POST Example (From FireBug):
-----------------------------26439188689323 Content-Disposition: form-data; name="imageFiles"; filename="WWKDK33.jpg" Content-Type:
image/jpeg
PNG ��� IHDR��"��"����xÕj��7IDATxÚíÚKÂ
ÐÞÿÒz�B3~Þ,Õb|nHàøÈ!B"D"D!B$!B"D"D!B$
!B"Dcdtå]µ
B"D!BÔKtb_xv-!B"Dunð+¯uÔ"D!BÑS*ï"B"D!B(Õl
B"D!B
ô¢ïü·½ä~"D!B¢URi,ÖÕ"D!BQ/Q:ò[*E"D!B¨a¼ÙôWÿéf"D!B¢]
HæL~eD!B"DöÍ_ÉòGGkA"D!BèD±}Çõò4
!B"DZôÀ½rª�"D!B¢eD¡¡y¡éøk!B
"D!ZGÔ;¯49ÛD!B"D"cöÊ#fåQ^D!B"D®I4_à|Ci#J!B"DÝ(s°
"D!B¢{7 £ÌÁ"D!B"D½DgBæant¿"D!BÑÖý¤ôm
"D!B"D"D!B$!B"A"D!D!B"A"D!ß|ÜYÆ
®«����IEND®B`
-----------------------------26439188689323 Content-Disposition: form-data; name="uploaderMode"
tournament
-----------------------------26439188689323--
Anyone any clues as to why it doesn't work? Thanks!
The issue is because when you send a FormData object in the request you have to set contentType to false so that no content-type header is sent. Try this:
if (asFormData) {
cType = false;
processData = false;
}
Also note that you could remove the need to send the asFormData property to your function entirely by just checking the type of the data property:
if (data.constructor == FormData) {
cType = false;
processData = false;
}
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+"®ion=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>
Please help. I'm working on a MVC project using dropzone upload multiple files based on this sample http://venkatbaggu.com/file-upload-in-asp-net-mvc-using-dropzone-js-and-html5/.
I have this work on Chrome, but I could not figure out why it doesn't work on IE 11. When I debug in VS2013, it doesn't seem to trigger the SaveUploadedFile action. Again, it works in Chrome. Below is the codes in my MVC project:
View:
#Styles.Render("~/Content/css")
<div class="container">
<div class="jumbotron">
<form action="~/PhotoAlbum/SaveUploadedFile/#Model.AlbumID" method="post" enctype="multipart/form-data" class="dropzone" id="dropzoneForm">
<div class="fallback">
<input name="file" type="file" multiple />
<input type="submit" value="Upload" />
</div>
</form>
</div>
</div> <!-- /container -->
<style type="text/css">
.dz-max-files-reached { background-color: red; }
</style>
#section scripts {
#Scripts.Render("~/bundles/dropzonescripts")
<script type="text/javascript">
//File Upload response from the server
Dropzone.options.dropzoneForm = {
maxFiles: 20,
init: function () {
this.on("maxfilesexceeded", function (data) {
var res = eval('(' + data.xhr.responseText + ')');
});
this.on("onSuccess", function (data) {
alert("Upload successfully!");
});
this.on("onError", function (data) {
alert("Upload Failed!");
});
this.on("addedfile", function (file) {
// Create the remove button
var removeButton = Dropzone.createElement("<button class='btn btn-info glyphicon glyphicon-remove-sign'> Remove </button>");
alert("Upload Failed!");
// Capture the Dropzone instance as closure.
var _this = this;
// Listen to the click event
removeButton.addEventListener("click", function (e) {
// Make sure the button click doesn't submit the form:
e.preventDefault();
e.stopPropagation();
// Remove the file preview.
_this.removeFile(file);
// If you want to the delete the file on the server as well,
// you can do the AJAX request here.
});
// Add the button to the file preview element.
file.previewElement.appendChild(removeButton);
});
}
};
</script>
}
Action:
public ActionResult SaveUploadedFile(int id)
{
EZone_PhotoAlbum ezAlbum = repoAlbum.GetPhotoAlbumByID(id);
bool isSavedSuccessfully = true;
string fName = "";
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
fName = file.FileName;
if (file != null && file.ContentLength > 0)
{
var originalDirectory = new DirectoryInfo(string.Format("{0}\\", Server.MapPath(sMapPath + "\\" + ezAlbum.AlbumFolder)));
string pathString = System.IO.Path.Combine(originalDirectory.ToString(), "original");
var fileName1 = Path.GetFileName(file.FileName);
bool isExists = System.IO.Directory.Exists(pathString);
if (!isExists)
System.IO.Directory.CreateDirectory(pathString);
var path = string.Format("{0}\\{1}", pathString, fileName1);
file.SaveAs(path);
}
}
if (isSavedSuccessfully)
{
return Json(new { Message = fName });
}
else
{
return Json(new { Message = "Error in saving file" });
}
}
.Headers:
General:
Remote Address:[::1]:80
Request URL:http://localhost/eZone/PhotoAlbum/SaveUploadedFile/2
Request Method:POST
Status Code:200 OK
Response Headers: view parsed
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 5.1
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAABDh+CIwTbjqQAAAAA=
Date: Fri, 26 Jun 2015 16:01:30 GMT
Content-Length: 26
Request Headers view parsed
POST /eZone/PhotoAlbum/SaveUploadedFile/2 HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 3501896
Authorization: Negotiate oXcwdaADCgEBoloEWE5UTE1TU1AAAwAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAABXCiOIGAbEdAAAAD6cslqGeHsjhn4ZY5uX0W2mjEgQQAQAAAPUXp1AtIpqEAAAAAA==
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySvGz79kd1fOGLop0
Accept: application/json
Cache-Control: no-cache
X-Requested-With: XMLHttpRequest
Referer: http://localhost/eZone/photoalbum/Detail/2
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Request Payload
------WebKitFormBoundarySvGz79kd1fOGLop0
Content-Disposition: form-data; name="null"
------WebKitFormBoundarySvGz79kd1fOGLop0
Content-Disposition: form-data; name="null"
------WebKitFormBoundarySvGz79kd1fOGLop0
Content-Disposition: form-data; name="file"; filename="IMG_0057.JPG"
Content-Type: image/jpeg
------WebKitFormBoundarySvGz79kd1fOGLop0--
.Response:
{"Message":"IMG_0057.JPG"}
I'm trying to make a file upload with Ajax in CodeIgniter but my Jquery code doesn't seem to be getting the data from the form although it seems like the file is in the POST message.
This is my controller:
public function upload_images(){
$files = $_FILES;
$data=array();
if(!empty($_FILES)){
$_FILES['userfile']['name']= $files['userfile']['name'];
$_FILES['userfile']['type']= $files['userfile']['type'];
$_FILES['userfile']['tmp_name']= $files['userfile']['tmp_name'];
$_FILES['userfile']['error']= $files['userfile']['error'];
$_FILES['userfile']['size']= $files['userfile']['size'];
$this->upload->initialize($this->set_upload_options());
$uploaded=$this->upload->do_upload();
echo json_encode($data);
}else{
echo 'empty';
}
}
This is my view:
<div class="main-content" >
<h1><?php echo $name=$_POST['name']?></h1>
<div class="form-group">
<?=#$error?>
<div id="formulario_imagenes">
<span><?php echo validation_errors(); ?></span>
<?=form_open_multipart(base_url()."index.php/ticketadmin/upload_images",'id="form_upload_front"')?>
<input type="file" id="foto1" name="userfile" /><br /><br />
<input id="btnsavefront" type="submit" value="Upload" />
<?=form_close()?>
</div>
</div>
</div>
The Javascript:
$(document).on('click','#btnsavefront',function(event){
//alert('hola soy el boton guardar');
//event.preventDefault();
$('#form_upload_front').submit(function(){
//event.preventDefault();
var fileId = document.getElementById('foto1');
console.log(fileId);
var formData = new FormData(),
dir_url='<?php echo site_url('ticketadmin/upload_images');?>';
formData.append('foto1', fileId.files[0]);
//console.log(formData);
$.ajax({
url: dir_url,
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
/*dataType: "json",*/
success: function(data){
//console.log(data);
}
});
});
//$('#form_upload_front').submit();
});
And this is the header from Network
Remote Address:192.168.33.10:80
Request URL:http://fbpostester.com/index.php/ticketadmin/do_upload
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:345809
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryBV6NO2YxjAQZBFNN
Cookie:ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%222f96b04f42abccfe2403af1c17527312%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%22192.168.33.1%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A109%3A%22Mozilla%2F5.0+%28Windows+NT+6.1%3B+WOW64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F36.0.1985.143+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1409332543%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D31089f37bfc2cd6b239ad6ef538e1f02e9743309
Host:fbpostester.com
Origin:http://fbpostester.com
Referer:http://fbpostester.com/index.php/ticketadmin/do_upload
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36
Request Payload
------WebKitFormBoundaryBV6NO2YxjAQZBFNN
Content-Disposition: form-data; name="userfile"; filename="PROPUESTA 2B.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryBV6NO2YxjAQZBFNN--
Response Headersview source
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:840
Content-Type:text/html
Date:Fri, 29 Aug 2014 17:15:50 GMT
Keep-Alive:timeout=5, max=100
Server:Apache
Vary:Accept-Encoding
X-Pad:avoid browser bug
X-Powered-By:PHP/5.3.10-1ubuntu3.13
Well let me help you,
So here is your form
<form method="POST" class="myForm" enctype="multipart/form-data">
<!-- add your span and pther stuff here-->
<input type="file" id="foto1" name="userfile" />
<input type="button" value="submit" onclick="submitFile();" />
</form>
here is your javascript
function submitFile(){
var formUrl = "url of your php";
var formData = new FormData($('.myForm')[0]);
$.ajax({
url: formUrl,
type: 'POST',
data: formData,
mimeType: "multipart/form-data",
contentType: false,
cache: false,
processData: false,
success: function(data, textSatus, jqXHR){
//now get here response returned by PHP in JSON fomat you can parse it using JSON.parse(data)
},
error: function(jqXHR, textStatus, errorThrown){
//handle here error returned
}
});
}
hope this code was helpfull
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.