Setting a custom content-type xmlhttprequest - javascript

I have an API I am trying to interface with that requires a custom content-type header be set, with the value text/xmlmc
I've implemented this like so
Xmlmc.prototype.submitRequest = function (request,callback) {
var self = this;
var port = portMap[request.service] || 5015;
var endpoint = this.endpoint = 'http://' + this.server + ':' + port;
var xml = request.toXml();
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// IE 5 and 6 makes us sad. Please don't use it
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//handle request
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
var response = self.handleResponse(xhttp);
callback(response);
}
};
xhttp.open('POST',endpoint,true);
xhttp.setRequestHeader('Content-type', 'text/xmlmc');
//xhttp.setRequestHeader('Content-length', xml.length.toString());
if(this.sessionCookie != '') {
xhttp.setRequestHeader('Cookie', this.sessionCookie);
}
xhttp.send(xml);
};
The endpoint is localhost:5015
When I do this, the request fails and never even sends. When I use a standard request header like 'text/plain' the request is sent but returns a status code of 501 not implemented. How can I set a custom HTTP header in an xmlhttprequest?

It turns out this was due to a cross origin issue. Even when the domain is the same, if the ports are different it is a problem. I fixed the issue by adding a reverse proxy to my apache configuration and now I can query the api without cross origin requests. Unfortunately I don't have access to change the API and allow cross origin domains.

Related

Get client IP in javascript/angularjs

I'm trying to get client IP in my angular app.
I'm using this code:
$http.get("http://l2.io/ip.js").then(function(response) {
$scope.ip = response.data;
});
But it make
Error: XMLHttpRequest cannot load http://l2.io/ip.js. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9001' is therefore not allowed access.
How to add headers?
There is a service provider that provides CORS headers (Access-Control-Allow-Origin: *) for javascript based requests:
https://freegeoip.com
Test the following XMLHTTP request for a sample:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(xhttp.responseText)
}
};
xhttp.open("GET", "//freegeoip.net/json/?callback=", true);
xhttp.send();
Or in case of jQuery Use:
$.getJSON('//freegeoip.net/json/?callback=?', function(data) {
console.log(data);
});

Javascript HTTP request authentication error

I am trying to call a webservice but I get a authentication error. It is a cross origin request. I have set the 'withcredentials' attribute to manage cross origin requests. But i am still getting the same error.
SOAPClient._loadWsdl = function(url, method, parameters, async, callback)
{
var wsdl = SOAPClient_cacheWsdl[url];
if (wsdl + "" != "" && wsdl + "" != "undefined")
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
var xmlHttp = SOAPClient._getXmlHttp();
if (SOAPClient.username && SOAPClient.password) {
xmlHttp.open("GET", url + "?wsdl", async, SOAPClient.username, SOAPClient.password);
var auth = "Basic " + SOAPClient._toBase64(SOAPClient.username + ":" + SOAPClient.password);
xmlHttp.withCredentials = true;
//xmlHttp.setRequestHeader( 'Access-Control-Allow-Origin', 'www.website.com');
xmlHttp.setRequestHeader('Authorization', auth);
} else {
xmlHttp.open("GET", url + "?wsdl", async);
}
if (async) {
xmlHttp.onreadystatechange = function() {
alert(xmlHttp.readyState);
if (xmlHttp.readyState == 4)
SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
}
xmlHttp.send(null);
if (!async) `enter code here`
return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
I suspect this is due to limitations of the browser that won't allow you to do a CORS request. The header would have to be set on the remote server to permit this and it sounds like you don't control it.
Create a server proxy at the domain of the page that can fetch the desired result from the other domain and relay it to you from the allowed domain.
You may want to post the URL of the WDSL server to see if other people can consume it.
p.s.
&& wsdl + "" != "undefined")
This will never evaluate to undefined because you are always concatenating an empty string.

XMLHttpRequest response: preflight request does not pass the access control check:

I am trying to subscribe to a firebase cloud messaging topic with the following http post request:
var data = null;
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://iid.googleapis.com/iid/v1/etLaB36oW1w...nyO_Zc26ZPOFTeNuf58-l6uSoJ9Xs1JRYKfqxsmKkdrR-oX4tQsuS_z5C0/rel/topics/Byfjordskole");
xhr.setRequestHeader("authorization", "key=AAAABlxTfxY:APA91bGE3sa09zq...dZSIVJul3N-y1hMJqAoKngwjC_El3rEuH4_-S2gOxKcdAF67HHhGK7pAWJrhyt8JthJGm_QN6JdXTBow62nYodgFvLncfSniwtBinBgIPLaKpT");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("postman-token", "a3ce72a5-f8ba-99e4-59d6-fe3295b84f6e");
xhr.send(data);
This works when I use Postman, but I get the following error message when I try to use the same code on my javascript app:
XMLHttpRequest cannot load https://iid.googleapis.com/iid/v1/eOEiRqvhD4s:APA91bFFb-uP-Xhf2iD-ALUI_X4M7…gA_YgQgmuib7cCL7UuSdlhUUWmsqwRnkcO2kpAIV_H-_xBPlPd/rel/topics/Eiganesskole.
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://sk......e.top' is therefore not allowed access.
Do firebase cloud messaging inhibit me from making this types of request, or is there a solution to this problem? Any help will be highly appreciated.
This Stack Overflow answer solved my problem: https://stackoverflow.com/a/2067584/6177181
The problem was browser security related: and this kept me from making cross domain requests. The Solution was to wrap my code in script tags to avoid this restriction. So instead of doing this request from another javascript file, I simply added the request code in the index.html file like this:
<script>
function subscribe(currentToken){
"use strict"
let stored_topics = localStorage.getItem("topicsList");
let topics = JSON.parse(stored_topics);
for (let i = 0; i < topics.length; i++){
let data = null;
let xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
let body = {};
let url = "https://iid.googleapis.com/iid/v1/"+currentToken+"/rel/topics/"+topics[i];
xhr.open("POST", url);
xhr.setRequestHeader("authorization", "key=AAAABlxTfxY:....QAVfBJI8J0RdZSIVJul3N-y1hMJqAoKngwjC_El3rEuH4_-S2gOxKcdAF67HHhGK....2nYodgFvLncfSniwtBinBgIPLaKpT");
xhr.setRequestHeader("content-type", "application/json");
xhr.send(data);
}
}
</script>
(The currentToken is requested from the firebase cloud messaging API in the same file(index.html)).
Follow the instructions on this link :https://firebase.google.com/docs/cloud-messaging/js/receive for information about Firebase cloud messaging.

Content-security-policy and Facebook add-on. Not working

I am making a Firefox add-on. It needs to
1) Read the webpage
2) Based on that, send information in a POST to my site,
3) Display a text based on what my site returns.
I cannot get this to work on Facebook.com and I believe that it is due to Facebook's restrictive Content-security-policy. I cannot get the add-on content_script to send a POST.
I have tried:
var url = 'https://mysite.com';
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.onload = function () {
alert("returned");
};
request.send();
On non-Facebook sites this works. On Facebook, there is no activity in the Network tab. The console gives me an error:
Content Security Policy: The page's settings blocked the loading of a resource at ...
I have also tried doing something with an iframe:
var onload = "var url = 'https://mysite.com';
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.send();
request.onload = function(){alert();};";
var iframe_wrapper = window.document.createElement("div");
iframe_wrapper.innerHTML='<iframe onLoad="'+onload+'"; src="https://mysite.com"></iframe>';
window.document.body.appendChild(iframe_wrapper);
On non-Facebook sites, two calls are made: the inital iframe src call and then the call in the onLoad function.
On Facebook, only the iframe call is made, which is successful. The console then gives an error (first time I try):
ReferenceError: reference to undefined property la.stack
ReferenceError: reference to undefined property n.name
Is there a way around this? Note that this does work with my Chrome extension (I use the first straight-forward method).
Yes set the csp rules. I got this from another topic here: How to add Content Security Policy to Firefox extension
But this version is slightly different.
But copy paste this:
var httpRequestObserver =
{
observe: function(subject, topic, data)
{
Cu.reportError('observing req')
var httpChannel, requestURL;
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
if (httpChannel.responseStatus !== 200) {
return;
}
var cspRules;
var mycsp;
// thre is no clean way to check the presence of csp header. an exception
// will be thrown if it is not there.
// https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIHttpChannel
console.info('reading response headers on requestURL = ', requestURL)
try {
console.warn('trying to set init')
cspRules = httpChannel.getResponseHeader("Content-Security-Policy");
mycsp = _getCspAppendingMyHostDirective(cspRules);
httpChannel.setResponseHeader('Content-Security-Policy', mycsp, false);
console.warn('set init done')
} catch (e) {
try {
console.warn('trying to set fallback')
// Fallback mechanism support
cspRules = httpChannel.getResponseHeader("X-Content-Security-Policy");
mycsp = _getCspAppendingMyHostDirective(cspRules);
httpChannel.setResponseHeader('X-Content-Security-Policy', mycsp, false);
console.warn('fallback set done')
} catch (e) {
// no csp headers defined
console.warn('no csp headers defined so SHOULD be able to inject script here url = ' + requestURL);
return;
}
}
}
};
Cu.import('resource://gre/modules/devtools/Console.jsm');
/**
* #var cspRules : content security policy
* For my requirement i have to append rule just to 'script-src' directive. But you can
* modify this function to your need.
*
*/
function _getCspAppendingMyHostDirective(cspRules) {
var rules = cspRules.split(';');
var scriptSrcFound = false;
for (var ii = 0; ii < rules.length; ii++) {
if ( rules[ii].toLowerCase().indexOf('script-src') != -1 ) {
rules[ii] = 'script-src * \'unsafe-inline\' \'unsafe-eval\''; // define your own rule here
scriptSrcFound = true;
}
}
return rules.join(';');
}
Then on startup of addon run this code:
Services.obs.addObserver(httpRequestObserver, 'http-on-examine-response', false);
and on shutdown of addon run this code:
Services.obs.removeObserver(httpRequestObserver, 'http-on-examine-response', false);

How to send data from outside site to my server via AJAX?

I am written the bookmarklet, which takes pictures and videos from a site and must send it to my server via AJAX. The problem is in crossdomain AJAX request - I have got an error:
XMLHttpRequest cannot load http://mysite.com/community/bookmarklet/. Origin http://www.some-nice-site.com is not allowed by Access-Control-Allow-Origin.
How to solve data sending to my server from third-part sites?
Note: I use only plane javascript, this is the stipulation of development.
my code:
function getXmlHttp(){
var xmlhttp;
if (typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
} else {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
};
return xmlhttp;
};
function vote(data) {
var req = getXmlHttp();
req.onready = function() {
if (req.readyState == 4 & req.status == 200) {
alert('OK');
}
}
req.open('GET', 'http://mydomain.com/community/bookmarklet/');
req.send(JSON.stringify(data()));
};
function dataProcessing(){
//some processing
return data;
};
// I tried it, but not deeply understand.
function JSONPresponse(){
document.getElementById('popup_body').innerHTML = 'done!';
};
(function(){
function pasteIt(){
// this function is builds the form, which get data for dispatch to my server.
};
pasteIt();
document.getElementById('my_button').addEventListener('click', function() {vote(dataProcessing)}, false);
}());
It is quite clear... the site you are attempting is prohibiting connection from outside world. You can try by modifying your http headers in request. See:
Access-Control-Allow-Origin Multiple Origin Domains?
Cannot properly set the Accept HTTP header with jQuery
As #jakeclarkson told - JSON-P is the solution, not the only, but useful for me.
XMLHttpRequest is not needed anymore. Instead it vote(data) function creates the script to build URL with params:
function vote(data) {
var script = document.createElement('script'),
data = JSON.stringify(data());
script.type = 'text/javascript';
script.src = 'http://mysite.com/api/bookmarklet/?vids='+encodeURIComponent(data);
document.getElementsByTagName('head')[0].appendChild(script);
};
The script is fulfilled, so URL is called and params already in the server.

Categories