I'm using Angular 7 and I got a problem with Headers.
This is my code:
signin() {
let signinData = this.signinForm.value;
this.encoded = btoa("my-trusted-client:secret");
let header = new Headers();
header.append('Authorization', 'Basic ' + this.encoded);
header.append('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
this.http.post(this.url + '/oauth/token?grant_type=password&username=' + signinData.username + '&password=' + signinData.password, { headers: header })
.subscribe(data => {
console.log(data);
})
}
Output Error:
error: "Unauthorized"
message: "Unauthorized"
path: "/barometre/oauth/token"
status: 401
timestamp: "2019-04-19T12:35:47.699+0000"
When I test it on Postman I got the results:
Edit:
The problem was on the request signature. I changed this:
this.http.post(this.url + '/oauth/token?grant_type=password&username=' + signinData.username + '&password=' + signinData.password, { headers: header })
By This:
this.http.post(this.url + '/oauth/token', params, { headers: header })
with
let params: URLSearchParams = this.serialize(this.data);
and generate new function
serialize(obj: any): URLSearchParams {
let params: URLSearchParams = new URLSearchParams();
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var element = obj[key];
params.set(key, element);
}
}
return params;
console.log(params);
};
You need to pass HttpHeaders in post. Check here
const header= {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Authorization': 'Basic ' + this.encoded
})
};
Also make sure that your Authorization token is valid.
The problem was on the request signature. I changed this:
this.http.post(this.url + '/oauth/token?grant_type=password&username=' + signinData.username + '&password=' + signinData.password, { headers: header })
By This:
this.http.post(this.url + '/oauth/token', params, { headers: header })
with
let params: URLSearchParams = this.serialize(this.data);
and generate new function
serialize(obj: any): URLSearchParams {
let params: URLSearchParams = new URLSearchParams();
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var element = obj[key];
params.set(key, element);
}
}
return params;
console.log(params);
};
Related
I can't download file from my friend service java code from angular that i implement and i don't know how to implement download file from angular please help me
My Code Angular
private _download$ = new Subject<void>();
**this._download$.pipe(switchMap(()=>this._downloadFile())).subscribe(resultBlob =>{
console.log("Success to Next ")
this.loadFile(resultBlob)
},(exception:any)=>{
console.log("exception: ",exception)
},()=>{
console.log("Complete: ")
})
}**
**private _downloadFile(){
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/octet-stream',
responseType : 'blob',
Accept : 'application/octet-stream',
observe : 'response'
})
};**
return this.http.get<Blob>('/col-corecollection-service/exclusion/download-file/'+this.exclusionCode,httpOptions)
}
private download(){
this._download$.next();
}
loadFile(data: any) {
var blob = new Blob([data], {type: 'application/octet-stream'});
var downloadURL = window.URL.createObjectURL(data);
window.open(downloadURL);
}**
And I have code service that my friend implement like this
#GetMapping("/exclusion/download-file/{exclCode}")
#ResponseStatus(HttpStatus.OK)
public ResponseEntity<Resource> exclusionDownloadFile(
#Size(min = 1, max = 50)
#PathVariable String exclCode
) {
if (!this.exclusionService.existsExclusionById(exclCode)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Exclusion code " + exclCode + " not found.", null);
}
SearchExclFilenameExclBlobByIdResponse downloadFile = this.exclusionService.searchExclFilenameExclBlob(exclCode);
byte[] fileData = downloadFile.getExclBlob();
Resource resource = new InputStreamResource(new ByteArrayInputStream(fileData));
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + downloadFile.getExclFilename() + "\"")
.body(resource);
}
when i click my download button and then it can't downloadFile to me please help
Try passing responseType outside headers
Remove responseType from header:
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/octet-stream',
Accept : 'application/octet-stream',
observe : 'response'
})
};
Here is updated code for passing responseType outside headers:
return this.http.get<Blob>('/col-corecollection-service/exclusion/download-file/'+this.exclusionCode,{headers: httpOptions.headers, responseType: 'blob'})
Then if you want download use fileSaver:
var file = new Blob([data], { type: "application/octet-stream" });
this.fileSaverService.save(file);
I use ngx-filesaver which provides the fileSaver directive.
<button class="mdi mdi-download btn btn-primary"
fileSaver
[fileName]="'yourfile.xxx'"
[url]="'/col-corecollection-service/exclusion/download-file/' + this.exclusionCode"
(change)="upload($event)">
Download
</button>
I have a problem downloading a file from a rest api using angular 6
Back-end method
#RequestMapping(value = "/print/{id}")
public ResponseEntity<byte[]> generateReport(#PathVariable("id") long id_project){
Map<String, Object> mapper = new HashMap<String, Object>();
byte[] content = exportService.export(mapper, ReportUtils.testReport, ReportUtils.FileFormat.PDF.toString());
return new ResponseEntity<>(content, Utils.getPDFHeaders("Situation_test.pdf"), HttpStatus.OK);
}
Mathod getHeader
public static HttpHeaders getPDFHeaders(String fileName) {
HttpHeaders head = new HttpHeaders();
head.setContentType(MediaType.parseMediaType("application/pdf"));
head.add("content-disposition", "attachment; filename=" + fileName);
head.setContentDispositionFormData(fileName, fileName);
head.setCacheControl("must-revalidate, post-check=0, pre-check=0");
return head;
}
My Angular Service
download(url: string): any {
let headers = new HttpHeaders();
headers = headers.append('Authorization', 'Bearer ' + this.getToken());
this.http.get(this.API_URL + url, {headers: headers}).subscribe((res) => {
const file = new Blob([res], {
type: 'application/pdf',
});
const a = document.createElement('a');
a.href = this.API_URL + (<any>res)._body;
a.target = '_blank';
document.body.appendChild(a);
a.click();
return res;
}, error => {
let alert: any = {
title: 'Notify Title',
body: 'Notify Body',
};
alert.body = error.error.message || JSON.stringify(error.error);
alert.title = error.error.error;
alert = this.alertService.handleError(error);
alert.position = 'rightTop';
console.log(error);
this.alertService.notifyError(alert);
return error;
});
}
I have already tried my API using PostMan and it word perfectly but in Angular it give me this error
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:8080/api/projects/print/1", ok: false, …}
error: {error: SyntaxError: Unexpected token % in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "%PDF-1.4↵%����↵3 0 obj↵<</Filter/FlateDecode/Lengt…25f1>]/Root 8 0 R/Size 10>>↵startxref↵1049↵%%EOF↵"}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:8080/api/projects/print/1"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:8080/api/projects/print/1"
Try adding content-type to your request headers.
You can try this as an exemple:
let headers = new Headers({'Content-Type': 'application/pdf', 'Accept': 'application/pdf'});
I am working with springmvc and angularjs. I'm trying to send the String response from springmvc controller to the angular controller, but facing the below error message shown on the browser console and the response which returned from springmvc is not getting printed in the angularjs side.
ERROR:
SyntaxError: Unexpected token s in JSON at position 0
at JSON.parse ()
Sample code:
js:
myApp.controller('myTestCtrl', function ($rootScope, $scope,MyService) {
$sco[e.submitInfo = function(){
var data = new FormData();
var allInfo =
{
'name': $scope.name,
'id': $scope.id,
'product': $scope.product,
'message':$scope.message
}
//files to be attached if exists
for (var i in $scope.filesAttached) {
var file = $scope.filesToAttach[i]._file;
data.append("file", file);
}
MyService.sendAllInfo(data).then(
function (response) {
if (response === "") {
alert("success");
//logic
}else{
alert("in else part " + response);
}},
function (errResponse) {
console.log("Error while retrieving response " + errResponse);
});
};
});
}});
MyService:
myService.sendAllInfo = function (data) {
var deferred = $q.defer();
var repUrl = myURL + '/myController/allInfo.form';
var config = {
headers: {'Content-Type': undefined},
transformRequest: []
}
$http.post(repUrl,data,config)
.then(
function (response) {
alert("response json in service: "+ response);
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while getting response.data'+ errResponse);
deferred.reject(errResponse);
}
);
return deferred.promise;
};
Spring mvc:
#RequestMapping(value = "/allInfo", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public #ResponseBody
String allInfoData(#RequestParam("data") String data,#RequestParam("file") List<MultipartFile> files){
//logic
return "success";
}
In my above spring controller code, i'm returning success string to angularjs controller, but in the browser the below error is displayed.
SyntaxError: Unexpected token s in JSON at position 0
at JSON.parse ()
Note: Above is only the sample code , it is perfectly hitting the spring controller and issue is only while catching the response from spring controller to angular controller.
I tried to change produces=MediaType.TEXT_PLAIN_VALUE to produces={"application/json"} but still it is showing the same error.
To avoid parsing the string, use transformResponse: angular.identity:
myService.sendAllInfo = function (data) {
̶ ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
var repUrl = myURL + '/myController/allInfo.form';
var config = {
headers: {'Content-Type': undefined},
transformRequest: [],
//IMPORTANT
transformResponse: angular.identity
}
var promise = $http.post(repUrl,data,config)
.then(
function (response) {
alert("response json in service: "+ response);
return response.data;
},
function(errResponse){
console.error('Error while getting response.data'+ errResponse);
throw errResponse;
}
);
return promise;
};
Also avoid using the deferred Anti-Pattern.
In the response there are some values which are simple text not String so You're asking it to parse the JSON text something (not "something"). That's invalid JSON, strings must be in double quotes.
If you want an equivalent to your first example:
var s = '"something"';
var result = JSON.parse(s);
The best solution is use responseType: "text" as "json" it will woke
I'm trying to calling a Java RESTful service by an html page, but I always get errors like the below:
No 'Access-Control-Allow-Origin' header is present on the requested resource", 405 (Method Not Allowed)
My simplest Java code is:
#SuppressWarnings({ "unchecked", "rawtypes" })
#RequestMapping(value = "/prenotazioni/{id}", method = RequestMethod.POST)
public ResponseEntity<Prenotazione> updatePrenotazione(HttpServletResponse response, #PathVariable int id, #RequestBody Prenotazione obj) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
try {
prenotazioneService.updatePrenotazione(id, obj);
} catch (Exception e) {
return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<Prenotazione>(obj,HttpStatus.OK);
}
And the html code is:
$('#btnSalva').on('click', function(e){
//Creo la stringa JSON nel formato atteso dal servizio RESTful
var obj = '{"aula":{"id":' + $("#id_aula").val() + '},"id_utente":1,"data_inizio":"' + $("#datetimepicker1").data().DateTimePicker.date() + '","data_fine":"' + $("#datetimepicker2").data().DateTimePicker.date() + '"}';
var id = $("#id_evento").val();
var url = "http://localhost:8080/gestione_aule/prenotazioni/" + id;
//With $.post I've got error: No 'Access-Control-Allow-Origin
$.post( "http://localhost:8080/gestione_aule/prenotazioni/" + id, obj );
//With $.ajax I've got error: 405 (Method Not Allowed)
/*$.ajax({
url: "http://localhost:8080/gestione_aule/prenotazioni/" + id,
type: "POST",
crossDomain: true,
data: obj,
dataType: "jsonp",
success:function(result){
alert(JSON.stringify(result));
},
error:function(xhr,status,error){
alert(status);
}
});*/
/*$.postJSON = function(url, data, callback) {
return jQuery.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
'type': 'get',
'url': url,
'data': JSON.stringify(data),
'dataType': 'jsonp',
'complete': function(e){
alert("c " + e);
},
'success': function(e){
alert("s " + e);
},
'error': function(e){
alert("e " + e);
}
});
};
$.postJSON(url, obj, function(e){alert(e);});*/
});
I've tried:
with and without specify response header in java servlet
mapping PUT and POST method
using $.post $.ajax
setting dataType json and jsonp
and many other combinations :)
But anyone worked for me... any suggest please?
Note: as I wrote in the code with $.post I've got error: No 'Access-Control-Allow-Origin, with ajax I've got error: 405 (Method Not Allowed)
Thans
The problem here that CORS (cross domain support) has 2 types of request:
Simple - such as HEAD, GET and POST. POST with content-type: application/x-www-form-urlencoded, multipart/form-data or text/plain
The rest requests are called Preflight requests
Your CORS request is a Preflight one. In Preflight requests the browser fires 2 requests:
OPTIONS - asking the server to verify that the origin, method and additional headers are trusted
The actual request - in your case POST
To fix the issue your case, add a new mapping that will handle the OPTIONS request:
#RequestMapping(value = "/prenotazioni/{id}", method = RequestMethod.OPTIONS)
public void updatePrenotazione(HttpServletResponse response, #PathVariable int id) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
response.addHeader("Access-Control-Allow-Headers", "accept, content-Type");
}
I get the following error when I try to call a java restful service from angularjs:
POST http://localhost:8080/test/info/ 405 (Method Not Allowed)
This is the angularjs code
...
$http.defaults.headers.common['content-type'] = 'application/json';
$http.defaults.headers.common['content-type'] = 'application/json';
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata;
var userdata = { username: 'test', password: '123456' };
$http({ method: 'POST', url: '/test/info', data : userdata })
.success(function (userdataResponse) {
$rootScope.userData = userdataResponse;
});
...
And this is the java code
#POST
#Path("/test/info")
#Produces("application/json")
#Consumes("application/json")
public Response getDataUserInformation(Userdata request){
Userdata user = userService.findByUser(request.getUser());
Gson gson = new Gson();
DataUserDTO dataUserDTO = dataUserService.findByID(user.getID());
return Response.ok().entity(gson.toJson(DataUserDTO).toString()).build();
}
What's the problem? I have a same function for the login and works well but this not...
Thanks for your help
Is it working with the following? The .json might be needed.
$http({ method: 'POST', url: '/test/info.json', data : userdata })
.success(function (userdataResponse) {
$rootScope.userData = userdataResponse;
});