As the title explains, I pretend to retrieve in console.log a custom header named "count" inside a map from an http.get request. The browser shows that the count value exists. How can I retrieve that value?
This is what I have tried, the problem is that this returns null.
import { Http } from "#angular/http";
constructor (public http: Http) {}
myFunction() {
return this.http.get(url)
.map((response: Response) => {
console.log(response.headers.get('count')); // returns null
});
}
response.headers only gets this
Nevermind, I fixed it adding count to the Access-Control-Expose-Headers on the website that provides the service.
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: ['count']
Related
even this exemple i found on the site of garmin has the same problem
https://developer.garmin.com/connect-iq/core-topics/https/
import Toybox.System;
import Toybox.Communications;
import Toybox.Lang;
class JsonTransaction {
// set up the response callback function
function onReceive(responseCode as Number, data as Dictionary?) as Void {
if (responseCode == 200) {
System.println("Request Successful"); // print success
} else {
System.println("Response: " + responseCode); // print response code
}
}
function makeRequest() as Void {
var url = "https://www.garmin.com"; // set the url
var params = { // set the parameters
"definedParams" => "123456789abcdefg"
};
var options = { // set the options
:method => Communications.HTTP_REQUEST_METHOD_GET, // set HTTP method
:headers => { // set headers
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED},
// set response type
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED
};
var responseCallback = method(:onReceive); // set responseCallback to
// onReceive() method
// Make the Communications.makeWebRequest() call
Communications.makeWebRequest(url, params, options, method(:onReceive));
}
}
can some one please tel me what i am doing wrong
The return code -400 means "Response body data is invalid for the request type." according to the SDK specification.
You are requesting a response type of Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED but in your question you state that you are expecting HTML to be returned, which almost certainly can't be parsed as URL encoded form parameters.
The SDK does not seem to support HTML response types. Even if you omit the expected response type, the server will probably still send "application/html" and the SDK states that "If the Content-Type header from the response is not one of the known HTTP_RESPONSE_CONTENT_TYPE_* types, an error will occur", so I guess you're out of luck.
Maybe you can try to request HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN in order to get the server to return text instead of HTML, which you then could use somehow?
I'm curious about the difference between axios interceptor and default header.
I want to add authorization in header.
I know I can manage authorization header with axios interceptor and default header.
(Attach Authorization header for all axios requests)
I'm not sure when to use the interceptor and default header respectively.
Is it simply that axios provides two methods?
Default headers are assigned statically. The values you place into them must be known at the time your code executes.
axiosOrInstance.defaults.headers.common["x-value"] = "some value you must know";
Interceptors are functions that execute per request / response. This means they can access values that might not have been available earlier or even values specific to the current request.
axiosOrInstance.interceptors.request.use(config => ({
...config,
headers: {
...config.headers,
"x-value": "whatever"
}
}), null, {
synchronous: true,
runWhen: config => config.url === "only/run/for/this/url"
})
They can also be asynchronous and make other async calls before resolving
axiosOrInstance.interceptors.request.use(async config => {
const someValue = await getSomeAsyncValue()
return {
...config,
headers: {
...config.headers,
"x-value": someValue
}
};
});
I have axios request in my vue application:
async get_banner(id:number) : Promise<any> {
return global.axios.get(`${process.env.VUE_APP_DOMAIN}/banners/${id}`)
}
it works while banner/${id} response exits, but I have situation when I should disable banner in my admin panel so api endpoint becomes empty. (not exits) so I am getting Request failed with status code 404 in my vue app console.
question is how to prevent error and know if url exits or not? what is best practice to do this?
You can't tell whether an API exists or not without trying it (or relying on another API to get status of the former API)
It's usually just a manner of handling the response properly. Usually this would look something like this...
getTheBanner(id){
this.errorMessage = null; // reset message on request init
get_banner(id)
.then(r => {
// handle success
this.results = r;
})
.catch(e => {
// handle error
if (e.status === 404){
// set error message
this.errorMessage = "Invalid banner Id";
}
})
}
then in your template you could have something like this
<div v-if="errorMessage" class="alert danger">{errorMessage}</div>
Explaination:
Yes, you're absolutely right. This is the default behavior of strapi. Whenever the response is empty it throws a 404 error. This is basically because the findOne method in service returns null to the controller and when the controller sends this to the boom module it returns a 404 Not Found error to the front end.
Solution:
Just override the find one method in the controller to return an empty object {} when the response is null.
Implementation
// Path - yourproject/api/banner/controllers/banner.js
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
/**
* Retrieve a record.
*
* #return {Object}
*/
async findOne(ctx) {
const { id } = ctx.params;
const entity = await strapi.services.restaurant.findOne({ id });
// in case no entity is found, just return emtpy object here.
if(!entity) return {};
return sanitizeEntity(entity, { model: strapi.models.restaurant });
},
};
Side Note:
There's no need to make any changes to the browser side axios implementation. You should always handle such cases in controller rather the client side.
Reference:
Backend Customizations
I seem to get empty body content of a Go http.Request if the method is DELETE. But if I change the method to POST, then the body content gives me the content I expect.
The relevant code from my golang looks like this:
import(
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
func Delete(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
qs := r.Form
log.Println(qs)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/profile", Delete).Methods("POST")
router.HandleFunc("/profile", Delete).Methods("DELETE")
}
Now when I run this JavaScript code form my browser:
fetch(sendurl,{
method:"POST",
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
body:"data="+project.encodeFormURIComponent(JSON.stringify({"ids":[1032,1033]}))
})
.then(response=>{
if(response.ok)
return response.json();
})
.then(result=>{
console.log(result);
})
I see a nice array of numbers in my qs[ids] in my Golang code. But if I change my method:"POST" to method:"DELETE" in the JavaScript, then qs is empty.
What am I doing wrong?
UPDATE
This JavaScript with the DELETE method can populate the Go qs variable the way one would normally expect:
fetch(sendurl+"?data="+project.encodeFormURIComponent(JSON.stringify({"ids":[1032,1033]})),{
method:"DELETE",
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response=>{
if(response.ok)
return response.json();
})
.then(result=>{
console.log(result);
})
So it seems Go will ignore JavaScript body argument when DELETE method is used, but it will respect the query string content in the API endpoint url? Why is it like that?
https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
The query string is part of the target-uri of the request; in other words, the query string is part of the identifier, not an incidental modifier of it. But the message-body of the request is not part of the identifier.
So your local framework, or any of the other general purpose components forwarding your request, are not required to provide support for the message-body.
Think "undefined behavior" in C.
I am doing a PUT request to RESTfull service which changes password of a user. For the time being I have just hardcoded values of new and old password in my AJAX test my service. However it is giving me a 400 error.
AJAX call
$.ajax({
type: "PUT",
url: "api/teachers/"+user,
data: {"old":"123","new":"qwe"},
contentType: "application/json",
success: function(data,status)
{
datax = data;
alert(data+status);
ko.applyBindings(new AddMarkSheetKo(data));
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert(XMLHttpRequest+textStatus+ errorThrown);
// error handler here
}
});
Restful function:
#PUT
#Path("/{name}")
#Consumes(MediaType.APPLICATION_JSON)
public Response changePwd(#PathParam ("name")String name,#QueryParam ("old") String old, #QueryParam("new") String nw){
System.out.println("entered function"+old+nw);
Teacher t = DataAccessUtil.getByName(Teacher.class, name);
if(t.getPassword().equals(old)){
t.setPassword(nw);
DataAccessUtil.update(t);
return Response.ok().build();
}
else{
return Response.status(Status.BAD_REQUEST).entity("Wrong password !!!").build();
}
//return reposnse;
}
This information might be useful that on the console it prints
entered functionnullnull
So it the restfull function is called however it is not receiving the query parameters.
Any help would be really appreciated!
First, you could replace the #QueryParam annotations with #FormParam ones to retrieve the 'new' and 'old' parameters of the PUT request. Then, you should remove the #Consumes("application/json") annotation and contentType:application/json from your server and browser side code, and finally replace the submitted data in JSON format into something like 'new=qwe&old=123'.
If you want to stay with a content in JSON format, you should probably map the incoming body with an entity (ie, a Java class annotated with JAXB annotations), so that the JAX-RS implementation you use could unmarshall the incoming JSON content into a Java object.
HTH.