Access-Control-Allow-Origin headers in GAS - javascript

I am sending an (HTTP GET) $.ajax request (from jsfiddle) to my Google Apps Script server and I get the following error:
XMLHttpRequest cannot load https://script.google.com/macros/s/mykey?params.
Origin http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin.
What is the best way to solve this problem?
I have successfully implemented jsonp $.ajax requests to retrieve json data and javascript using this GAS/jsfiddle configuration. However, I seem unable to accomplish this jsonp success this time. Possibly because I am going through an .updaterow() function (per jqWidgets?)
My research:
This post almost asks a similar question except it is not specific to GAS.
I do not think GAS allows one to set server-side response headers. But surely there must be a way to get my request to execute?
Perhaps this question explains it better? (GAS issue) Is there a workaround solution? (Come on creative people.)

GAS does not allow CORS headers at this time.

Related

modify getJSON to work with CORS

I am looking for ways to allow cross-domain access using $.getJSON. I came across solutions which suggest that using CORS is the solution to this problem. But most of the solutions have a general ajax format.
I cannot use JSONP since I get data from a server which I do not have access. Is there a way to modify this code using $.getJSON to get the data?
$.getJSON(jsonURL, function(res){
console.log(JSON.stringify(res));
});
Or do I have to use ajax format for CORS?
Server which I do not have access
I think, this will break your neck.
You need some kind of access to the server or contact someone who has. At least you have to adjust the HTTP-Header to enter your domain Access-Control-Allow-Origin is the keyword.
Have a look at MDN
If you have access to set the HTTP Response Headers for the page that loads your JS scripts, then YES you can use CORS to send cross-domain requests. However, this is not supported in older browsers.
You need to set the Access-Control-Allow-Origin header, e.g.
Access-Control-Allow-Origin: *
Or
Access-Control-Allow-Origin: http://host-of-other-site.com
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

How to make a JSONP POST request in angular?

The $http.jsonp method described in the official documentation seems to always perform get requests: http://docs.angularjs.org/api/ng.$http#methods_jsonp.
I have tried setting the config option to 'POST' but it still sends a GET:
$http.jsonp('/api/new?callback=JSON_CALLBACK', {method: 'POST'});
I have also tried setting a data argument in the hope that angular would switch to a POST:
$http.jsonp('/api/new?callback=JSON_CALLBACK', {data: {stuff: true}});
But it still doesn't :)
As for making a post like this:
$http.post('/api/new?callback=JSON_CALLBACK')
It does make a POST obviously but doesn't do the angular magic thingy with the JSON_CALLBACK and produces the following JS error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://xxx.yyy.zzz' is therefore not allowed access.
(The API is not on the same server as the app, that's the point of JSONP).
Google was most unhelpful on this issue and reading through angular's sources is not the easiest task. So how can I make a JSONP POST request with angular?
You cannot make a POST request using JSON-P (with or without Angular)
A JSON-P request works by generating a <script> element with a src attribute. This will always trigger a GET request.
If you want to make a cross-domain POST request with JavaScript then you must use either XMLHttpRequest (and have the server supply suitable access control headers as per the CORS specification) or proxy the request through the server hosting the page.

Google Geocoding ajax request with Yahoo YUI 3

I understand the way to make an ajax call in YUI 3 is using the IO utility.
I want to get the address of a location from Google's geocoding API.
<script type="text/javascript"><!--
YUI().use('io-base', function(Y) {
function complete(id, o) {
var data = o.responseText; // Response data.
alert(o.responseText);
};
Y.on('io:complete', complete, Y);
var request = Y.io("http://maps.googleapis.com/maps/api/geocode/json?language=en&sensor=false&latlng=12,34);
});
//-->
</script>
I get a reply with method OPTIONS and status code 405 Method Not Allowed.
I believe this is because of some "preflight" permission check. I do not receive the desired response. If I copy and paste the url into the browser, I see the json data.
I could post the ajax request to a php script on my own domain and get the json response with curl.
But why have this extra step if I could just get the data in javascript?
So what can I do to solve this? Is the IO utility not the right library to use?
You're making a cross-domain XHR request, and running into the "Same origin policy", a generic restriction in client-side JavaScript. See for example Why do I still receive 405 errors even though both URLs are from XXXX.com?
There are various ways to work around this problem:
1) Make a server-side request in PHP, as you suggest
2) Use the YUI jsonp module
3) Use the YUI YQL module, which proxies your request through Yahoo! servers and handles JSONP housekeeping for you
There are many other ways to tackle this problem, but those three should get you started.
Y.io has support for cross domain requests. See http://yuilibrary.com/yui/docs/io/#cross-domain-transactions
You need to properly config it with the "xdr" property, and load the "io-xdr" module, etc. This example uses it as well: http://yuilibrary.com/yui/docs/io/weather.html

How can I get HTTP response header using JS?

I tried so many tutorials online but everything I try is really old and fails - I can't even create an XMLHTTPRequest object!
I just want to get the header from google.com - how can I do that?
You would use xhr.getResponseHeader() to get a single header, or xhr.getAllResponseHeaders() to read all of the headers from an XMLHttpRequest response.
The reasons this won't work for you:
XMLHttpRequest is case sensitive. If you are using HTTP in all caps, it will fail.
Unless you are a google employee adding code to google.com, your request falls victim to the same origin policy. You'll have to use your server as a proxy to get headers from a google request.
You cant simply do this by JS. You'll have to use AJAX and do a server request to PHP,ASP, Java or whatever. The XMLHTTPRequest should do it - if you really want to do it manually. But it will really not work with foreign domains, so you are forced to do the XMLHTTTPRequest to a page on your server which will deliver the header.

Sending POST message with AJAX Problem

I am currently trying to send a POST message which works fine except for the error that there are not correct credentials. However, after I add the credentials header, the message type is changed into OPTIONS and fails. I do not understand how adding a header causes the type to change to OPTIONS. Any help would be appreciated.
ajaxRequest = $j.ajax({
url: url,
type: 'POST',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth),
}
success: function(data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function(xhr, desc, err) {
console.log(xhr);
alert('fail')
console.log("Desc: " + desc + "\nErr:" + err);
}
});
EDIT: just to be more clear, I can literally go in and comment out the setRequestHeader function and it sends the message POST.
The problem you're encountering is because of cross-domain restrictions when using AJAX. When you try to set an authorization header, the browser issues what's known as a pre-flight request to see if the server will accept requests from this domain.
A pre-flight request is typically sent as an OPTIONS request. If the server you're invoking doesn't return an Access-Control-Allow-Origin header that matches your domain, the AJAX request is blocked.
There's more on this here: Cross-Origin Resource Sharing
"User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin."
I've run into the same problem- there are a few possible workarounds depending on your scenario.
If you have any way of setting the above mentioned header on the 3rd party server (some applications/services offer this) then that's probably the easiest way.
There's also a javascript library called EasyXDM that may work for you, but again, it will only be of use if you have access to the 3rd party server to upload a configuration file for this library.
Other options to investigate are PostMessage and Cross Domain Iframe communication. The latter is more of an old-school hack, the former is the recommended approach for newer browsers. It won't work for IE6/7.
The option we will probably end up using is a simple proxy- invoke our own server with the AJAX request, and on the server invoke the 3rd party server. This avoids the cross domain issue entirely, and has other advantages for our scenario.
I guess this is a problem in Internet Explorer. without explicitly telling the request-method (POST|GET) the request header doesn't contain the custom-header in IE, but it works in other browsers.
Yet try to post this in the bugs for jquery. Also try in other browsers.
Edit 1 : I saw this as a bug in jQuery 1.4.x .... I reported a bug report now.
The OPTIONS response happens when the server does not know how to respond to the ajax request.
I've seen it happen often when trying to post to a third-party domain (i.e. cross-site posting)
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
Have you tried:
Having some sort of callback on the url that is being posted to?
Explicitly setting the headers (I'm assuming you're using PHP) on the url that is being posted to?

Categories

Resources