Hello Guys I have made an React Native Application using Expo and I have a question regarding a fetch call.
Lets say this is my fetch call:
const getMonthReport = async () => {
await fetch("http:/xxx/jasperserver/rest_v2/reportExecutions", {
method: "POST",
headers: {
"Accept": "application/xml",
"Content-Type": "application/xml"
},
body: { ... }
});
}
How can I pass my XML as the body of the request? It looks like this:
<reportExecutionRequest>
<reportUnitUri>/Test/MonthReport2</reportUnitUri>
<async>false</async>
<freshData>true</freshData>
<saveDataSnapshot>false</saveDataSnapshot>
<outputFormat>html</outputFormat>
<interactive>false</interactive>
<parameters>
<reportParameter name="allHrs">
<value>90:00</value>
</reportParameter>
<reportParameter name="holidayHrs">
<value>07:36</value>
</reportParameter>
<reportParameter name="illHrs">
<value>18:00</value>
</reportParameter>
</parameters>
</reportExecutionRequest>
Related
I have attempted to create a request in javascript, that has previously worked using python just fine.
the following is an accurate representation of the code I used to post the request with python:
url = 'https://website.com/api/e1'
header = {
'authorization': 'abcd1234'
}
payload = {
'content': "text",
}
r = requests.post(url, data=payload,headers=header )
This (above) works just fine in python.
now what I did in javascript is the following:
payload = {
"content": "this is text",
};
fetch("https://website.com/api/e1", {
method: "POST",
headers: {
"authorization":
"abcd1234",
},
body: JSON.stringify(payload),
});
but this is returning the error
400- Bad request
When using data parameters on python requests.post, the default Content-Type is application/x-www-form-urlencoded(I couldn't find it on the document, but I checked the request. If you know, please leave a comment).
To achieve the same result with fetch, you must do as follows.
const payload = {
'content': 'this is text',
};
fetch('https://website.com/api/e1', {
method: 'POST',
headers: {
'authorization': 'abcd1234',
},
body: new URLSearchParams(payload),
});
You don't need to do this body: JSON.stringify(payload), rather you can simply pass payload in body like this body:payload
React code for build jsonBlob object
function jsonBlob(obj) {
return new Blob([JSON.stringify(obj)], {
type: "application/json",
});
}
exportFTP = () => {
const formData = new FormData();
formData.append("file", jsonBlob(this.state.ipData));
alert("Logs export to FTP server")
axios({
method: "post",
url: "http://localhost:8080/api/auth/uploadfiles",
data: formData,
headers: {
Accept: "application/json ,text/plain, */*",
"Content-Type": "multipart/form-data",
},
});
};
Spring boot backend that accepts for frontend request
public class UploadFile {
#Autowired
private FTPClient con;
#PostMapping("/api/auth/uploadfiles")
public String handleFileUpload(#RequestParam("file") MultipartFile file) {
try {
boolean result = con.storeFile(file.getOriginalFilename(), file.getInputStream());
System.out.println(result);
} catch (Exception e) {
System.out.println("File store failed");
}
return "redirect:/";
}
I want to figure out when I called the function from the frontend it's working properly but I change the state its doesn't send the object to the backend while the file appears in the directory. if I delete the file then only send it again and save it on the directory.
How I save multiple files while doesn't delete the previous ones
Thank you very much for your time and effort.
"Content-Type": "multipart/form-data",
Don't set the Content-Type yourself when posting a FormData.
The Content-Type needs to contain the boundary value that's generated by a FormData(example: multipart/form-data; boundary=----WebKitFormBoundaryzCZHB3yKO1NSWzsn).
It will automatically be inserted when posting a FormData instance, so leave this header out.
When you append blobs to a formdata then it will default the filename to just "blob"
On the backend you seems to override the file all the time:
con.storeFile(file.getOriginalFilename(), file.getInputStream());
Generate a new unik name if you want to keep all files
of topic but why not go with the fetch api? Smaller footprint. don't require a hole library...
fetch('http://localhost:8080/api/auth/uploadfiles', {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json ,text/plain, */*'
}
})
In React application I used props to pass the file name from a different state and make sure to remove,
"Content-Type": "multipart/form-data",
Main function in React,
exportFTP = ({props from different state}) => {
const formData = new FormData();
formData.append("file", jsonBlob(this.state.ipData),{You can use this parm for pass name});
alert("Logs export to FTP server")
axios({
method: "post",
url: "http://localhost:8080/api/auth/uploadfiles",
data: formData,
headers: {
Accept: "application/json ,text/plain, */*"
},
});
};
And back end code I used same to get the original name then Its appears with the right name.
con.storeFile(file.getOriginalFilename(), file.getInputStream());
Chears !!
I would like to disable cache on getting a request in vue environment. I already tried this but it does not work.
api.js (file)
getCall: () => {
return performAsyncGet(apiConfig.getCall.url,
requestConfigJSON, _REQUEST_TOKENS.getCall, apiConfig.getCall.cache)
.then(
response => response.data
);
},
(apiConfig.js) (file)
getCall: {
url: `${servicePathPrefixOrDomain}/api/getCall`
cache: false
}
Does anybody know how to disable the cache, when making a get request in vue.js?
Thanks in advance!
To avoid caching you can make your url unique by appending timestamp as a querystring parameter like this:
getCall: {
url: `${servicePathPrefixOrDomain}/api/getCall?_t={new Date().getTime()}`
cache: false
}
In this way for every ajax call the url will be unique due to different timestamp and browser will not cache the response.
Is solved adding the next code in the header:
const requestConfigJSON = {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
};
html-javascript
var csrftoken = $('[name="csrfmiddlewaretoken"]').val();
$('#Save').click(function () {
var ajaxdata = {
exam: $('#Exam').val()
};
$.ajax({
url: '/save',
type: 'POST',
dataType: 'json',
data: JSON.stringify(ajaxdata),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
"X-CSRFToken": csrftoken
},
credentials: 'include',
success: function () {
alert(ajaxdata);
console.log(ajaxdata);
},
error:function (xhr, ajaxOptions, thrownError){
console.log(ajaxdata);
}
});
}
views.py
import json
from django.http import HttpResponse
def save(request=request):
data = json.loads(request.body)
testexam = data['exam']
testexam = request.POST.get('exam')
testobj = MyObject.objects.filter(name="David").first()
testobj.Exam = testexam
testobj.save()
return HttpResponse(json.dumps({"success": True}), content_type="application/json")
These are my html and views now.
Removed the "flask" part.
data = json.loads(request.body)
allowed me to receive data successfully!
Still don't quite understand why " request.POST " didn't work.
I'll come back later to update if I manage to know the reason!
Thanks for the comments and useful suggestions!
No need using the flask.
This is how I receive the data:
data = json.loads(request.body)
and it all works well!
Thanks for all the comments, suggestions, answers! Really appreciated!
your ajax code is just fine, however you're doing few things wrong. First of all, in your html part.
<h1> This is simple html</h1>
<input type="text" id = "Exam">
<button type="button" id="Save">Save</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var csrftoken = $('[name="csrfmiddlewaretoken"]').val();
$('#Save').click(function () {
var ajaxdata = {
exam: $('#Exam').val()
};
$.ajax({
url: '/save',
type: 'POST',
dataType: 'json',
data: JSON.stringify(ajaxdata),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
"X-CSRFToken": csrftoken
},
credentials: 'include',
success: function () {
alert(ajaxdata)
},
error:function (xhr, ajaxOptions, thrownError){
console.log("this is an error")
}
});
});
</script>
You were initiating the ajaxdata before the click event happened, which may lead to the null value of #Exam filed.
Now getting back to your Flask part, you can't do request.POST with the data sent through Ajax request. Rather you can access all the data you sent through your js with request.data, below is the code which is working successfully.
from flask import Flask, request,send_from_directory
import json
# set the project root directory as the static folder, you can set others.
app = Flask(__name__)
#app.route('/home')
def root():
#return "this is home"
return send_from_directory("/home/ekbana/Documents/","index.html")
#app.route('/save',methods=['POST'])
def save(request=request):
print(request.data.decode("utf-8")) #We need to decode because it's a byte
#not a string
data = json.loads(request.data.decode("utf-8"))
#data here is {'exam': 'a text'} a dict in this case
testexam = data["exam"]
testobj = MyObject.objects.filter(name="David").first()
testobj.Exam = testexam
testobj.save()
return HttpResponse(json.dumps({"success": True}), content_type="application/json")
This is working fine with me, I replicated a simple example for your requirement. Aslo make sure to use methods=["POST"] if you want your route to recieve the POST request, if you didn't specify it, it may lead to HTTP_405_METHOD_NOT_ALLOWED.
I'm using Vue.js 2 and the I18n plugin to create a multilanguage website. The required language file (in my example nl) is requested from an external url. Unfortunately I can't get it working.
function getLanguage() {
return Vue.http({
url: '/language/nl_NL.json',
method: 'get',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then(
response =>
response.json(),
() => {
/* Error */
}
);
}
Vue.config.lang = 'nl';
Vue.locale(Vue.config.lang, getLanguage());
console.log(getLanguage());
The /language/nl_NL.json file is a json file. The network connection is ok (returns 200) and the console.log() command is showing a Promise. But the translation across my website is not working. Vue.locale is not setting the file as a translation file and I can't figure out the problem.