Making POST request in Tampermonkey to Google Apps Script - javascript

I am using Tampermonkey to monitor a webpage for certain changes, which I am trying to record in a Google Sheet. To do this, I have a Google Apps Script, and I want to make POST requests to the Apps Script.
A snippet of my code in Tampermonkey is shown below:
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://script.google.com/macros/s/~~scriptId~~/exec", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
However, I am getting an error that says Access to XMLHttpRequest has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource, and a net::ERR_FAILED 404 as well.
I know that data is correct, since it has been logged to the console. I have also deployed the Apps Script as a Web app, and setting it to execute as Me and for Anyone to have access.
I do not have much experience with JavaScript, so any help would be appreciated. Is there anything I can do to fix this?
Edit: I resolved it by changing the code to
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://script.google.com/macros/s/~~scriptId~~/exec?"+data, true);
xhr.send();

For documentation, here another solution for this case
(tested in Chrome only)
Script in Tampermonkey:
// #grant GM.xmlHttpRequest
function test() {
var obj = {};
obj.param_0 = "abc";
obj.param_1 = "xyz";
sending_xml(obj);
}
function sending_xml(obj) {
console.log("SENDING DATA");
GM.xmlHttpRequest ({
method: "POST",
url: "https://script.google.com/macros/s/[DEPLOYMENT_ID]/exec",
data: JSON.stringify(obj),
headers: {
"Content-Type": "application/json"
},
onload: function (response) {
console.log(response); //display "ok"
}
});
}
Code.gs
function doPost(e) {
var string = e.postData.getDataAsString();
var data = JSON.parse(string);
Logger.log(data);
//do stuff;
return "ok";
}
//must be deployed as WebApp, with "Access to All"

Related

Ajax Call empty response on Google chrome Mobile

i searched for an answer that fix my problem a lot, but none of the topic fit my scenario..
I have to make an AJAX call inside my application, it work fine on ALL desktop browser, and on SOME mobile browser (for example on my ASUS zenPhone native browser it work correctly, even on my iPhone from work (FF and Safari)) but no way in google Chrome (mobile), in this one the call complete but the response it's empty (only empty, no error provided)... i ask some friend to test it too and similar result occours (empty response) .... i have an https server and an https endpoint
there is my code:
<script>
var x = Math.floor((Math.random() * 10000000) + 2000);
var data = JSON.stringify({
"Token": x,
"Subject": "testAPI"
});
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
//console.log(this.responseText);
var dataJ = JSON.parse(this.responseText);
var dataA = dataJ.Questions;
alert(dataA[0].img);//this is already empty on my mobile :(
dataA.forEach(function(entry) {
//console.log(entry);
});
}
});
xhr.open("POST", url);
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
</script>
Server side CORS are enabled, and as i said it works flawless on all desktop i tested on ... i don't know if i can provide the url to you guys(i have to ask # the API provider) but if you give me some hints it would be nice ...
thanks a lot for your time!
[EDIT]
after some trouble i get an error(Testing remotly from my phone to my PC with dev tools)
Failed to load resource: net::ERR_INSECURE_RESPONSE
on the other device i didn't get this error...
This is a long shot but, try to set the content type header to :
xhr.setRequestHeader("content-type", "text/plain");
This should suppress the CORS preflighting done by chrome which causing the empty response.

Chrome Extension blocked from a rails API

I am just trying to talk with a REST api on a Rails site.
I am using a Chrome extension and javascript to make a CORSRequest.
I get this error whenever I try to make a request:
XMLHttpRequest cannot load https://MYWEBSITE.com/api/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'chrome-extension://mychomreextensioncode' is therefore not allowed access. The response had HTTP status code 404.
Here is my current code:
function makeCorsRequestLogin() {
var url = "https://MYWEBSITE.com/api/login";
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onload = function() {
var text = xhr.responseText;
var title = text; //getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onerror = function() {
alert('Woops, there\'s an error making the request.');
};
var password = document.getElementById("password").value;
var user_name = document.getElementById("username").value;
xhr.send(JSON.stringify({"user_name":user_name, "password":password}));
}
Elsewhere, in the past, people have said that this code solves it. But, I have no idea where this could would go.
# This is used to allow the cross origin POST requests made by confroom kiosk app.
def set_access_control_headers
headers['Access-Control-Allow-Origin'] = "*"
headers['Access-Control-Request-Method'] = %w{GET POST OPTIONS}.join(",")
end
I am only working in JS and HTML on a chrome extension. I do not have access to the ruby site. Can I solve this problem from only my end?
You should define permission for your server domain in the manifest.json.
"permissions": ["https://MYWEBSITE.com/*"]
Also make sure you set the right protocol whether it's http or https.

XMLHttpRequest receiving undefined

I'm making a widget on iphone but I can't get data from the url.
On IE, I can get data. However, on chrome and on iphone I can't get the data but it only shows undefined instead of data.
function a() {
var url="www.xxx.xxx";
var request = new XMLHttpRequest();
request.open('GET', url, false);
request.send();
xmlDoc = request.responseXML;
}
please help me!! I'm really appreciated for any answers.
Create a function something like below,to receive the data from server.
request.onreadystatechange = function(){
if(request.readyState == 4){
console.log(request.responseText);
}
}
Please make sure that you are making request from the same Origin. That means if you are in site www.abc.com then you can make request for www.abc.com/download/ or www.abc.com/site and so on. But if you request for www.gdb.com then it will probably fail with this error in your console "No 'Access-Control-Allow-Origin' header is present on the requested resource." The browser prevents this activity for security reasons. It needs to be on the same domain.
Try using JQuery sometimes. It's API is very easy to use and is very helpful for doing tasks. You will need to add the script to the page first like this:
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
You can download the script or use the live version and link to it like above.
Next you can make a call like this to make a GET request. Observer that it returns data when successful. This makes your job easy but remember you need to make call from same domain.
$.ajax({
type: "GET",
url: "http://wwww.something.com"
})
.done(function( data ) {
alert(data);
})
.fail( function(xhr, textStatus, errorThrown) {
alert(xhr.responseText);
});
To know more about Cross Site HTTP Requests: CORS
Here is a thread that may help you to understand better: “No 'Access-Control-Allow-Origin'
would setting the responseType work?
call the request.responseType = 'document'; before send.

How to make http authentication in REST API call from javascript

I need to call OpenMRS REST API from Java script to get data from OpenMRS. Below is my java script code:
function myfunction(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John", false);
xhr.setRequestHeader("Authorization: Basic YWRtaW46QWRtaW4xMjM");
xhr.send("");
alert(xhr.status);
}
Where YWRtaW46QWRtaW4xMjM is my base64 coded username:password as explained here. If I do not put the authorization line in the code and check the web app using Firebug, it returns 401 unauthorized status that is expected. But if I put the authorization, nothing is returned and in firebug I do not see any response as well. If I check the URL directly on browser, the page asks for username and password and after giving correct credential, it returns the data normaly. So I am getting some problem of providing the http authentication right from the java script of the app. I have also considered the methods explained here but no luck. Can anyone please help me to authorize the http request right from the javascript?
Here is another similar but different example of how to set the header for authorization purposes, but instead using JQuery and AJAX.
var token = "xyz"
var url = "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John"
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + token)
},
})
.done(function (data) {
$.each(data, function (key, value) {
// Do Something
})
})
.fail(function (jqXHR, textStatus) {
alert("Error: " + textStatus);
})
Below is also an example of how you might get an access token using xhr instead of AJAX.
var data = "grant_type=password&username=myusername#website.com&password=MyPassword";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://somewebsite.net/token");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("client_id", "4444-4444-44de-4444");
xhr.send(data);
Beware of cross-site domain requests(if you're requesting a token that's not on localhost or within the domain that you are currently working in), as you'll need CORS for that. If you do run into a cross-domain issue, see this tutorial for help, and be sure you have enabled CORS requests from the API as well.

Javascript CORS JSON/JSONP Request

I have browsed most CORS and JSON request topics, and cannot understand why this first script works, but not the second. I would love to be educated in the ways of CORS and Javascript and XMLHTTPRequest2 and AJAX.
This works:
function wfs() {
var url = 'http://routes.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/api/0.3/51.22545,4.40730,%5B51.22,4.41,51.2,4.41%5D,51.23,4.42/car.js?lang=de&units=miles&callback=getRoute';
var script = document.createElement('script');
script.type="text/javascript";
script.src=url;
document.getElementsByTagName('head')[0].appendChild(script);
}
function getRoute(response) {
console.log(response);
}
This does not work:
function wfs() {
var url = 'http://routes.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/api/0.3/51.22545,4.40730,%5B51.22,4.41,51.2,4.41%5D,51.23,4.42/car.js?lang=de&units=miles';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function(e) {
if (this.status == 200) {
var json = this.response;
console.log(json);
}
};
xhr.send();
}
Firebug shows a Red 200 Null Response.
However, the second script does work when I use a different url:
var url = 'http://ip.jsontest.com/?mime=2';
The first domain, http://routes.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/api/0.3/51.22545,4.40730,%5B51.22,4.41,51.2,4.41%5D,51.23,4.42/car.js?lang=de&units=miles, does not implement CORS (i.e. does not send a usable Access-Control-Allow-Origin header). http://ip.jsontest.com/?mime=2 does. There is nothing you can do about this -- it depends on the server.
The first block of code uses JSONP. What this actually does is inject a script tag into the document. Script tags can have external sources (if they are not of the same scheme, they may be blocked for security reasons). This allows the server to essentially send you javascript code that you insert into a <script> that gets run immediately.

Categories

Resources