Upload attachment using REST API

Blake April 4, 2017

Hi, feeling a bit desperate here....

I'm trying to create a file upload step in Blueprint wizard and I've spent 3+ days trying to get it to work using jQuery/AJAX and the upload attachment API. See: Upload an attachment

I've had success using curl in my terminal to execute the upload but every iteration I've come up with for an AJAX http request has had an error or issue with it. I've also been successful using jQuery for a similar task (creating a new page). 

Does anyone have a working example of a file upload using jQuery? Alternately, is there another method I might not be aware of? 

If you want to see my code, here's what I have at the moment:

 

    wizard.on('submit.page1Id', function(e, state) {
		var files;
		$('input[type=file]').on('change', prepareUpload);

		function prepareUpload(event)
		{
		  files = event.target.files;
		  console.log(files);
		}		
		$('input[type=file]').trigger('change');

		console.log(files);

		var data = new FormData();
		data.append('file', files[0]);
		
		console.log(data);
		console.log(files);
		console.log(files[0]);

		$.ajax
		  ({
			type: "POST",
			url: "http://localhost:1990/confluence/rest/api/content/917506/child/attachment",
			contentType:"multipart/form-data; boundary=------------------------021ab64c72420e84",
			async: false,
            cache: false,
			headers: {
				"Authorization": "Basic " + btoa("admin:admin"), "X-Atlassian-Token": "no-check"
			}, 
			data: JSON.stringify(data),
			success: function (){
				console.log('Attachment saved!'); 
			},
			error : function(xhr, errorText){
				console.log('Error '+ xhr.responseText);
			}
		});
    });

I've tried (and Googled) everything I can think of. It seems so simple yet I can't seem to get anything to work. Any suggestions?

2 answers

1 accepted

1 vote
Answer accepted
Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 5, 2017

Edit: What is your error message, if any.

Try changing the line

data.append('file', files[0]);

to 

data.append('file', files);

As far as i can see, the source maps the "file" into a list:

public RestList<Content> createAttachments(@PathParam("id") ContentId contentId,
                                               @MultipartFormParam("file") List<FilePart> fileParts,
                                               @Nullable @MultipartFormParam("comment") List<FilePart> comments,
                                               @Nullable @MultipartFormParam("minorEdit") List<FilePart> minorEdits) throws ServiceException
Blake April 5, 2017

Thank you Panos, I appreciate the suggestion. 

I tried changing it to: data.append('file', files);
and receive this error in the console: 
"AbortError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:1990/confluence/rest/api/content/917506/child/attachment'."

To give you a sense of the other things I've tried, so far I've: 

  • Added/removed: "async: false," 
  • Added/removed: "cache: false,"
  • Added/removed: "processData: false,"
  • Changed contentType between "multipart/form-data", "application/json", and "false"
  • Added/removed: "JSON.stringify()" from the data

Everything seems to throw an error of some sort or doesn't throw an error but aborts.

Any suggestions would be much appreciated!

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 5, 2017

I made it work with:

var files;
$('input[type=file]').on('change', prepareUpload);

function prepareUpload(event)
{
files = event.target.files;
console.log(files);
} 
path="/rest/api/content/92078504/child/attachment"
var actionData=new FormData();
actionData.append('file', files[0]);
actionData.append('comment', "foobar");
actionData.append('minorEdit', "true");
console.log(actionData);
AJS.$.ajax({
type: "post",
url: path,
data: actionData,
processData: false,
headers: {
"X-Atlassian-Token": "nocheck"
},
contentType: false,
cache: false,
success: function (data, status, response) {for (var pair of actionData.entries()) {
console.log(pair[0]+ ', ' + pair[1]); 
}},
error: function(response){console.log(response);}});

 

Like guidosch likes this
Blake April 6, 2017

THANK YOU!!! You have no idea how much I appreciate this. I spent days (and a few nights) on this without making any progress. 

I had to rework it a bit to work with my instance but it works perfectly. Thank you!

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 6, 2017

:) I am glad it worked!

Blake April 9, 2017

Hi Panos,

I was writing this rest call for attachments to be added to a new page when using the blueprint wizard however I can't find a way to specify the new page id (variable) in the rest call. Do you know if there is a way to do this or it is not possible because the page doesn't exist yet?

If it's not possible with the rest call, I'm guessing I would need to write java method/class to handle it using a listener on the BlueprintPageCreateEvent, right? If so, any chance you would be able to give me some direction or help me write something that would accomplish this?

I've gone through the Atlassian tutorials and have the event listener working but I'm hitting a roadblock. 

I found a potential solution described in a comment here: https://community.atlassian.com/t5/Confluence-questions/How-to-attach-upload-image-in-a-Wizard-of-the-Confluence/qaq-p/429457

The concept seems straightforward and makes sense but I can't figure out what's needed in the code because java is new to me. I'm willing to learn and I'm trying my best to get it working but I didn't realize I would need java and my project is due tomorrow. I would really appreciate any help, ideas, or direction!

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 11, 2017

Hello, please post a new question explaining what you want to do and when the attachment should be attached. I am not very familiar with blueprints myself.

abhinay006 April 11, 2017

I am getting following error while sending attachment to created issue on JIRA. 


<message>org.apache.commons.fileupload.FileUploadE xception: the request was rejected because no multipart boundary was found</message><stack-trace>java.lang.RuntimeExcep tion: org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found

I am making an ajax call to send this attachment as multipart-data. 

var blob = canvasImageDataUrl
var fd = new FormData();
fd.append("file", blob,"ss_"+issueKeyid+".png");

$.ajax({
url: "https://"+jiraUrl+"/rest/api/2/issue/"+issueKeyid +"/attachments",
type: 'POST', 
data: fd,
processData: false,
beforeSend: function (xhr) {
xhr.setRequestHeader ("X-Atlassian-Token", "no-check");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("charset", "UTF-8");
},
success: function(data) {
alert("issue created");

},
error:function(data){
console.log(data);
},
complete:function(xhr,status){
console.log(xhr);
}
});

 

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 11, 2017

please use a separate thread

Blake April 12, 2017

Abhinay, that's not the issue I'm having though I posted a comment that should help.  

Panos, I developed some java to try to accomplish what I'm describing however I'm running into a new issue here: PageManager Error when Copying Attachment (https://community.developer.atlassian.com/t/pagemanager-error-when-copying-attachment/2447).

Any help would be much appreciated!

Bernie January 1, 2018

@Panos below script worked for me.

 

curl -D- -u user1:Password1 -X POST -H "X-Atlassian-Token: no-check" -F "file=@available.sh_orig" "https://confluencewikiprod.intra.infineon.com/rest/api/content/62772085/child/attachment"

 

However, There's no label upon uploaded, Is there a way to put also a label name on it? Hope for your response...Thanks

Panos
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 1, 2018

According to this you can only add comment. If you want to add label you should do a separate call

Like Christophe Marchewka likes this
0 votes
Abdul Zubair June 6, 2017

I'm having a similar issue but I'm using axios. Can someone please check it out?

https://community.atlassian.com/t5/JIRA-questions/Uploading-attachments-via-REST-API-using-axios/qaq-p/593946

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events