Angular gzip json file automatically : Refused to set unsafe header "Accept-Encoding" - json

I use a gzip json static file on my server (actually, it's my test server) and the data i receive is always compressed.
Here is my code :
$http({
url :'app/assets/json/makes2v.json.gz',
method: "GET",
headers: { 'Accept-Encoding': 'gzip' }})
.success(function(data, status, headers, config) {
console.log(data);
});
I use angular 1.3.15 and Chrome.
In the console I have this error:
Refused to set unsafe header "Accept-Encoding"
Any help will be appreciated.
Thanks,

You shouldn't set the request header "Accept-Encoding". This is set automatically by the browser. See this Q&A for a list a browsers that accept gzip.
On the server side, you will need to set the Content-Encoding to:
Content-Encoding: gzip
Then the response should be automatically decompressed by the browser.

Related

how to get json from github [duplicate]

This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 9 months ago.
I can't get Repl.it to pull json from github. Do I need the api
or just a better url?
Errors:
While using the url https://raw.githubusercontent.com/Xiija/FakeDB/master/db.json
TypeError: NetworkError when attempting to fetch resource.
While using this url Xiija.github.io/JSON/db.json
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data.
But, when I add https to it https://Xiija.github.io/JSON/db.json
TypeError: NetworkError when attempting to fetch resource.
The request
const myHeaders = new Headers({
'Content-Type': 'application/json', // text/xml .. application/json
'Access-Control-Allow-Headers': '*',
'accept': 'application/vnd.github.v3.raw',
'user-agent': 'dataApi'
});
let tm = new Date().getTime();
const myRequest = new Request(url + '?time=' + tm, {
method: 'GET',
rejectUnauthorized: false,
insecureHTTPParser: true,
mode: 'cors',
cache: 'default',
headers: myHeaders,
});
Your problem is with CORS.
GitHub does not allow CORS pre-flight requests (OPTIONS requests) on GitHub Pages content (the xiija.github.io URL) or raw content (the raw.githubusercontent.com URL), so the browser decides that you are not permitted to access these URLs.
What you need is to avoid sending the pre-flight request. Your myHeaders code is the problem here: setting the Content-Type: application/json and Access-Control-Allow-Headers: *` is causing the pre-flight request.
For several reasons, you should not be sending any of the headers you are sending:
Content-Type header on a Request is only for requests that have a body (e.g. POST, PUT, PATCH), not for GET requests.
Access-Control-Allow-Headers header is for responses, not requests.
Accept header is only helpful if the server cares about it, but GitHub Pages and raw file access don't use it.
User-Agent is ignored by the browser and the browser's built-in user agent is sent instead.
Here is a version of your code that works:
const url = 'https://raw.githubusercontent.com/Xiija/FakeDB/master/db.json';
let tm = new Date().getTime();
const myRequest = new Request(url + '?time=' + tm, {
method: 'GET',
rejectUnauthorized: false,
insecureHTTPParser: true,
mode: 'cors',
cache: 'default',
});
fetch(myRequest).then(r => r.json()).then(r => console.log(r))

Can I send my cookies from domainA to domainB in header cookie

I currently have an client hosted on domainA. It reaches out to an endpoint on domainB and I would like to include the cookies from domainA in that request to domainB.
Right now the only cookies that are sent are cookies generated on my machine for domainB.
Is there some sort of security header I can set on the client that allows the sharing of its cookies with domainB or is this a security violation. I can always pass it through as a payload in the body, but it would be nicer if I could just use the withCredentials param to allow it.
// Request
const response = await axios({
method: method as Method,
baseURL,
endpoint,
data,
params,
headers: {
'content-type': 'application/json',
...authorization
},
withCredentials: true // allow sharing of cookies
});
Manually trying to set the cookie header results in the browser complaining Refused to set unsafe header "Cookie"
I think the solution involves the Access-Control-Allow-Headers header on the response headers, but I am unsure

Node-red - Posting data to influxdb via http

Im trying to post data to an Influxdb via Node-red.
Via CURL i can post this:
curl -i -XPOST 'http://localhost:8086/write?db=waterlevel' --data-binary 'vattenstand,lake=siljan,region=dalarna value=160.80'
and it puts data to InfluxDb.
When I try to post via Node-red and an HTTP request I get the error:
{"error":"unable to parse '{\"url\":\"http://192.168.1.116:8086/write?db=waterlevel\",\"method\":\"POST\",\"body\":\"vattenstand,lake=siljan,region=dalarna value=160.80\",}': missing tag value"}
I use this code in a function in Node-red and pass it to the HTTP request:
var dataString = 'vattenstand,lake=siljan,region=dalarna value=160.80';
msg.payload = {
'url': 'http://192.168.1.116:8086/write?db=waterlevel',
'method': 'POST',
'body': dataString,
};
msg.headers = {
Accept: "application/json"
};
return msg;
The sidebar help for the node details the msg properties you should be setting to configure the node.
You are passing in URL, method and body as properties of msg.payload. That is not correct.
They should be set as msg.url, msg.method for the first two, and msg.payload should be the body of the request.
In this instance, you have already configured the node with a URL and method directly, so there's no need to pass them in with the message. In fact, as you have configured the URL in the node you will find you cannot override it with msg.url. if you want to set the URL with each message, you must leave the node's URL field blank in the editor.
You may also need to set the content-type header.
Assuming you are happy to leave the URL and method hard coded in the node, you function should be something like:
msg.payload = 'vattenstand,lake=siljan,region=dalarna value=160.80';
msg.headers = {
Accept: "application/json"
};
msg.headers['Content-type'] = 'application/x-www-form-urlencoded';
return msg;
Why don't you use the spezial influxdb node?
https://flows.nodered.org/node/node-red-contrib-influxdb
Advantage: The http header need not be created. You can reuse the defined connection for other data.

AJAX works when extension is .json but not when it is .html

So I have an ajax request. When I use .html as below. I receive:
Failed to load resource: the server responded with a status of 406 (Not Acceptable)
When i use .json I receive the correct output. Why does it not work with .html
$("input[value = 'Add Type Targets']")
.click(
function() {
var promise = $
.ajax({
url : '/MyRoot/budget/myUrl.html',
type : 'GET',
beforeSend : function(
xhr) {
xhr
.setRequestHeader(
"Accept",
"application/json");
xhr
.setRequestHeader(
"Content-Type",
"application/json");
}
});
promise
.done(function(data) {
someCode
}
});
});
On the method I have
#RequestMapping(value = "/myUrl", method = RequestMethod.GET, produces = "application/json")
public #ResponseBody List<String> getData() {
return staticDataService.getData();
}
I have the jackson-mapper-asl-1.9.10.jar and jackson-core-asl-1.9.10.jar added.
Is it that because of the .html extension my response header is getting altered. Actually it is not even hitting my method when i use .html.
The HTTP error code 406 (Not Acceptable) means your HTTP request specified that the result must be of a certain type.
In your code, you explicitly mention that you only accept JSON results.
$.ajax({
url : '/MyRoot/budget/myUrl.html',
type : 'GET',
beforeSend : function(xhr) {
xhr.setRequestHeader( "Accept", "application/json");
...
When the server sees a file with a .json extension, it will automatically give it an application/json content-type, while a .html file, with be text/html content-type.
Since these are very different, you see the 406 error.
Since you are actually returning JSON, I would suggest you also use that for the extension. Not only will this help prevent confusion for other developers, it will also prevent you from having to 'fight the system'.
If you for some reason do want the HTML extension, you could try forcing the response content-type to be application/json. Since this extension based content-type is typically added by the server (IIS, Apache, etc.), it depends on your development stack if you can override this.
In ASP.NET you would use the following to explicitly set a header, but I can't say for sure if this will override the settings in IIS.
Response.ContentType = "application/json"
Should this not work, you can also change your AJAX call to be more permissive with it's response accepting.
xhr.setRequestHeader( "Accept", "*/*");

Cannot set content-type to 'application/json' in jQuery.ajax

When I have this code
$.ajax({
type: 'POST',
//contentType: "application/json",
url: 'http://localhost:16329/Hello',
data: { name: 'norm' },
dataType: 'json'
});
in Fiddler I can see following raw request
POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache
name=norm
But what I'm trying is to set content-type from application/x-www-form-urlencoded to application/json. But this code
$.ajax({
type: "POST",
contentType: "application/json",
url: 'http://localhost:16329/Hello',
data: { name: 'norm' },
dataType: "json"
});
Generates strange request (which I can see in Fiddler)
OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache
Why is that? What is OPTIONS when it should be POST there? And where is my content-type set to application/json? And request parameters has gone for some reason.
UPDATE 1
On server side I have really simple RESTful service.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
[WebInvoke(
Method = "POST",
UriTemplate = "Hello",
ResponseFormat = WebMessageFormat.Json)]
public string HelloWorld(string name)
{
return "hello, " + name;
}
}
But for some reason I can't call this method with parameters.
UPDATE 2
Sorry for not answering so long.
I've added these headers to my server response
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
It didn't help, I have Method not allowed error from server.
Here is what my fiddler says
So, now I can be sure that my server accepts POST, GET, OPTIONS (if response headers work like I expect). But why "Method not allowed"?
In WebView response from server (you can see Raw response on picture above) looks like this
It would seem that removing http:// from the URL option ensures the the correct HTTP POST header is sent.
I don't think you need to fully qualify the name of the host, just use a relative URL as below.
$.ajax({
type: "POST",
contentType: "application/json",
url: '/Hello',
data: { name: 'norm' },
dataType: "json"
});
An example of mine that works:
$.ajax({
type: "POST",
url: siteRoot + "api/SpaceGame/AddPlayer",
async: false,
data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
contentType: "application/json",
complete: function (data) {
console.log(data);
wait = false;
}
});
Possibly related:
jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox
After some more research I found out the OPTIONS header is used to find out if the request from the originating domain is allowed. Using fiddler, I added the following to the response headers from my server.
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
Once the browser received this response it then sent off the correct POST request with JSON data. It would seem that the default form-urlencoded content type is considered safe and so does not undergo the extra cross domain checks.
It looks like you will need to add the previously mentioned headers to your servers response to the OPTIONS request. You should of course configure them to allow requests from specific domains rather then all.
I used the following jQuery to test this.
$.ajax({
type: "POST",
url: "http://myDomain.example/path/AddPlayer",
data: JSON.stringify({
Name: "Test",
Credits: 0
}),
//contentType: "application/json",
dataType: 'json',
complete: function(data) {
$("content").html(data);
}
});​
References:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
http://enable-cors.org/
https://developer.mozilla.org/en/http_access_control
I can show you how I used it
function GetDenierValue() {
var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
var param = { 'productDenierid': denierid };
$.ajax({
url: "/Admin/ProductComposition/GetDenierValue",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
data: JSON.stringify(param),
success: function (msg) {
if (msg != null) {
return msg.URL;
}
}
});
}
So all you need to do for this to work is add:
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
as a field to your post request and it'll work.
I recognized those screens, I'm using CodeFluentEntities, and I've got solution that worked for me as well.
I'm using that construction:
$.ajax({
url: path,
type: "POST",
contentType: "text/plain",
data: {"some":"some"}
}
as you can see, if I use
contentType: "",
or
contentType: "text/plain", //chrome
Everything works fine.
I'm not 100% sure that it's all that you need, cause I've also changed headers.
If you use this:
contentType: "application/json"
AJAX won't sent GET or POST params to the server.... don't know why.
It took me hours to lear it today.
Just Use:
$.ajax(
{ url : 'http://blabla.example/wsGetReport.php',
data : myFormData, type : 'POST', dataType : 'json',
// contentType: "application/json",
success : function(wsQuery) { }
}
)
I found the solution for this problem here. Don't forget to allow verb OPTIONS on IIS app service handler.
Works fine. Thank you André Pedroso. :-)
I was fighting this same issue and it was caused by a lack of JSON.stringfy() i.e.
data: JSON.stringfy({ name: 'norm' }),
Hope this saves someone else a lot of time!
I had the same issue. I'm running a java rest app on a jboss server. But I think the solution is similar on an ASP .NET webapp.
Firefox makes a pre call to your server / rest url to check which options are allowed. That is the "OPTIONS" request which your server doesn't reply to accordingly. If this OPTIONS call is replied correct a second call is performed which is the actual "POST" request with json content.
This only happens when performing a cross-domain call. In your case calling 'http://localhost:16329/Hello' instead of calling a url path under the same domain '/Hello'
If you intend to make a cross domain call you have to enhance your rest service class with an annotated method the supports a "OPTIONS" http request. This is the according java implementation:
#Path("/rest")
public class RestfulService {
#POST
#Path("/Hello")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.TEXT_PLAIN)
public string HelloWorld(string name)
{
return "hello, " + name;
}
//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS
#OPTIONS
#Path("/Hello")
#Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
public Response checkOptions(){
return Response.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "Content-Type")
.header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS
.build();
}
}
So I guess in .NET you have to add an additional method annotated with
[WebInvoke(
Method = "OPTIONS",
UriTemplate = "Hello",
ResponseFormat = WebMessageFormat.)]
where the following headers are set
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "Content-Type")
.header("Access-Control-Allow-Methods", "POST, OPTIONS")
I got the solution to send the JSON data by POST request through jquery ajax. I used below code
var data = new Object();
data.p_clientId = 4;
data = JSON.stringify(data);
$.ajax({
method: "POST",
url: "http://192.168.1.141:8090/api/Client_Add",
data: data,
headers: {
'Accept': 'application/json',
'Content-Type': 'text/plain'
}
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
});
});
I used 'Content-Type': 'text/plain' in header to send the raw json data.
Because if we use Content-Type: 'application/json' the request methods converted to OPTION, but using Content-Type: 'test/plain' the method does not get converted and remain as POST.
Hopefully this will help some one.
Hi These two lines worked for me.
contentType:"application/json; charset=utf-8",
dataType:"json"
$.ajax({
type: "POST",
url: "/v1/candidates",
data: obj,
**contentType:"application/json; charset=utf-8",
dataType:"json",**
success: function (data) {
table.row.add([
data.name, data.title
]).draw(false);
}
Thanks,
Prashant
In the jQuery.ajax documentation, contentType specifies the type of content to send to the server. The default value is "application/x-www-form-urlencoded; charset=UTF-8".
For cross-domain requests, if a content type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain is set, the OPTIONS method will be sent in the request header. It is a check that ajax does by the CORS policies to check if the methods that you request to the server (in this case POST) in your domain, are allowed
If the OPTIONS method on your server where the API is hosted is allowed, the request you made to the server initially is made, in this case the POST is sent.
If you are making the request to the same domain and same port, the OPTIONS method is not sent. If this is the case, one of the solutions is to use "http://localhost:<port>..." or just use relative paths where you are going to make the request.
But if the REST API in your backend is in another domain, so there are two solutions.
Do not put in ajax contentType: "application/json", and send the data either in JSON format as an Object or as a string, or a string with the parameters to send type key=value.
Enable CORS in your Rest API (that is, allow OPTIONS, POST methods, for any domain, or your domain where you make the request).
The problem is that in some cases it is necessary to set the type of content to send as "application/json", because the server where the API is hosted does not accept other types of content.
If you have control over the BackEnd and the REST API, I recommend enabling CORS on it. (Also applies if it is the same domain but different port).
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
Or also allow other types of content like application/x-www-form-urlencoded or encode it in such a way that it also accepts strings with key=value parameters. This prevents jQuery from sending OPTIONS in its request header.
One last thing: if contentType: "application/json" is used and the server expects "application/json" as well, you should use JSON.stringify() on data, since when sending the request to the server, it seems to take the JSON as a string and not as an object. In my case, not using JSON.stringify() and using contentType: "application/json", returned me a server error with status 500