Below code is working properly now. But if I replace 'text.txt' with 'http://google.com' isn't showing anything, nor displaying an error.
What am I doing wrong?
I need this code to get content of an url to a string, on client side.
Thakns.
<script type="text/javascript">
var webUrl = 'text.txt';
var queryString = '';
var xmlText = getAjaxValues(webUrl, queryString);
window.alert(xmlText);
document.write(xmlText);
function getAjaxValues(webUrl, queryString)
{
var xmlHttpObject = new XMLHttpRequest();
xmlHttpObject.open("GET", webUrl, false);
xmlHttpObject.send();
var xmlText = xmlHttpObject.responseText;
return xmlText;
}
</script>
It's being prevented by the same origin policy, which requires that any AJAX requests, except for scripts and, by extension, jsonp, be made to servers in the same domain as the original page request. Your best bet is to create a proxy method on your server that can accept the url that you want to get the content of and have it request the page and pass it back to the client.
Related
With some help from this thread I came up with the code below. How can I fetch the Google Drive file ID, open the direct link to the file and snatch the virus scan confirm ID that is required to stream files over 100 MB and then puzzle back the link? I'm kind of stuck at the xhr part.
function fixGoogleDriveURL(url) {
if (url.indexOf('drive.google.com') !== -1) {
var DocIDfull = url;
var DocIDstart = DocIDfull.indexOf('open?id=');
if (DocIDstart == -1) {
// invalid
return url;
}
var DocID = DocIDfull.slice(DocIDstart+8);
url = 'https://drive.google.com/uc?export=download&id=' + DocID;
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
var token = xhr.responseText.match("/confirm=([0-9A-Za-z]+)&/");
window.location.replace(url + '&confirm=' + token[1]);
// should I add url += '&confirm=' + token[1] here instead of window.location?
}
}
};
xhr.open("GET", url);
xhr.send();
}
return url;
}
console.log(fixGoogleDriveURL('https://drive.google.com/open?id=1C25uoL6nIqqNhex3wm8VwODsO2q2pXBt') + "\n<-- should output:\nhttps://drive.google.com/uc?export=download&id=1C25uoL6nIqqNhex3wm8VwODsO2q2pXBt&confirm=XXXXX");
Scraping GDrive using Client-Side JavaScript isn't explicitly allowed by Google and therefore your Ajax call/XHR fails.
The only way to get around that restriction is by using a proxy in the middle that will forward Google's Website code but add appropriate Access-Control Allow-Origin Headers.
You can either use your own server for that (some minimal server-side script code will do) or you can use a service like http://multiverso.me/AllOrigins/ or https://corsproxy.github.io/ to proxy the request for you.
The AllOrigins site has some example code for use with jQuery, but basically they work by URI encoding the URL you want to access and appending that string to the site's proxy URL.
Here's an article by freecodecamp.org that outlines how to use these services (skip to the Don’t Let CORS Stop You! section.
Note: A security advice: These services are working fine right now, but they could go out of business tomorrow and start serving malicious data instead or redirect your file requests to completely different files or completely different websites altogether. It's up to you to decide if you want to trust these strangers or not.
Given two sub domains:
web.mysite.com and api.mysite.com
Currently making any request from web. to api. results in the preflight OPTIONS request being made. This wouldn't be so much of an issue if it didn't add an extra 600ms to requests in China.
I was told that setting document.domain = 'mysite.com'; in JS would resolve the issue but this hasn't helped at all.
Is it possible / how can I disable the OPTIONS request when sending to just a different sub domain.
Solved this using the iframe technique which seems to be what Facebook / Twitter do.
Steps below:
1) Set the document.domain to be the root domain. So given the url http://site.mysite.com/ I set the domain in JavaScript like document.domain = 'mysite.com';
2) Setup an iframe which pulls a HTML file from the API Domain.
<iframe id="receiver" src="http://api.mysite.com/receiver" style="position:absolute;left:-9999px"></iframe>
This is set to be positioned so it can't be seen.
3) Set the HTML of the receiver page to set the domain:
<!DOCTYPE html><body><script>document.domain='mysite.com'</script></body></html>
4) Added an onload event to the iframe to capture the window once its loaded.
onload="window.tempIframeCallback()"
5) Assign the child window to a variable.
window.tempIframeCallback = function() {
window.childWindow = window.receiver.contentWindow;
}
6) Make the XMLHttpRequest() from the childWindow instead of the main window.
var xhr = new window.childWindow.XMLHttpRequest();
Now all requests will be sent without a preflight OPTIONS request.
7) When using jQuery, you can also set the source of xhr in the settings:
$.ajax({
...
xhr: function() {
return new window.childWindow.XMLHttpRequest();
}
});
As a complement to #Phill's answer that deserves all the credits, here is the final html code, that also exposes the iframe's fetch function:
<!DOCTYPE html>
<html><body>
<script>
document.domain = 'mysite.com';
window.setupAPI = function() {
var receiverWindow = window.receiver.contentWindow;
// you may also want to replace window.fetch here
window.APIfetch = receiverWindow.fetch;
// same thing, you may as well replace window.XMLHttpRequest
window.APIXMLHttpRequest = receiverWindow.XMLHttpRequest;
}
</script>
<iframe id="receiver"
src="http://api.mysite.com/receiver"
style="position:absolute;left:-9999px"
onload="window.setupAPI()"></iframe>
</body></html>
And of course the HTML "http://api.mysite.com/receiver" should retrieve:
<!DOCTYPE html>
<html><body><script>
document.domain='mysite.com';
</script></body></html>
And then, within your JS code, you can now use APIfetch and APIXMLHttpRequest like you'd use fetch and XMLHttpRequest ... et voilà, no more preflight request whatever the method and content type used!
Here's an all javascript approach:
document.domain = 'mysite.net';
var apiIframe = document.createElement('iframe');
apiIframe.onload = function(){
window.XMLHttpRequest = this.contentWindow.XMLHttpRequest;
};
apiIframe.setAttribute('src', API_URL + '/iframe');
apiIframe.style.display = 'none';
document.body.appendChild(apiIframe);
where API_URL + '/iframe' returns this:
<!DOCTYPE html><body><script>document.domain = 'mysite.net'</script></body></html>
I wanna to send request form a webpage to chrome extension, and then in chrome extenison receive data and read data, is there any way to this?
Ex:
In doman www.nope.com/sendRequest.html will sent data to chrome extension via url chrome-extension://xxxxxxx/getData.htm?isToken=abc, and then extension will receive and can read data "isToken".
Here is my code in sendRequest.html
<script type="text/javascript">
function sendRequest() {
document.write("Sending request");
var req = new XMLHttpRequest();
req.open("POST", "chrome-extension://xxxxxxxxxx/getData.htm?isToken=abc", true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
alert(req.responseText);
document.write("OK");
}
}
};
req.send();
}
</script>
And in chrome extension file getData.htm, how can I get data?
(Edit: what type of data are you sending? Could you pass it through as a JSON encoded string, via GET? JSON.stringify() and JSON.parse() may be of use to you. :)
The following may be useful as a guide for accessing that POST/GET data. :) )
As far as I am aware, this is best done using some form of server side scripting. You could use window.location.search in JS, and split the string and perform the necessary functions, but I think server-side scripting may work best. :)
An example of a JS implementation could be as follows:
var url = window.location.search;
var params = url.substr(url.IndexOf("?") - 1, 30);
This would grab the parameters (starting at ? (inclusive), and continue for 30 chars. You could also use something like var params = url.substr(url.IndexOf("?") - 1, url.length); to get the whole parameters list.
How you use this from then on, is up to you, but you could pass it through a switch() or whatever you need. :)
Obviously, this being a chrome extension would limit your options regarding any server-side processing. :/
Edit: The above would go in getData.htm. :)
I'm trying to do a simple POST from a javascript (google chrome extension) to my google app
I can see that the HTTP POST is indeed sent to the GAE server, but I can't figure how to transfer a simple text string, and use it in the google app.
The goal: send a string from the javascript with xmlhttpRequest, show this string on google-app webpage.
Here's the code of the javascript:
function onRequest(request, sender, sendResponse) {
var url = request;
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://myapp.appspot.com");
xhr.send(url);
// Return nothing to let the connection be cleaned up.
sendResponse({});
};
Here's how I deal with the post in the server side:
def post(self):
url1 = str(self.request.get('url1'))
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('<p>URL is: %s</p>' % url1)
When I look at the POST response I see
<p>URL is: </p>
where is the var url that was sent?
I got it to work, in a different way. Instead of XMLHttpRequest, I used jquery:
$.post("http://myapp.appspot.com", { url1: request});
and it worked :)
BTW, I also discovered that if you want the chrome extension's html to use jquery, you need to do
<script src="jquery-1.5.1.js"></script>
<script> your code here </script>
(I'm sure it's basic for you guys but fresh for me :)
The content you include with xhr.send() will be in self.request.body, if it's not specified in CGI format. For your simple test, you might also try xhr.send("url1=" + request).
I am providing web service which return data as JSON object. The problem is with Ajax, Ajax can't call cross domain url. Is it possible to disable it?
You can't disable it, but you can solve the problem by accepting JSONP-requests.
Use JSONP if you can control what the other server responds.
JSONP has to return a javascript compliant script. (var hi = {json = stuff};)
Example for the client HTML:
// This is our function to be called with JSON data
function showPrice(data) {
alert("Symbol: " + data.symbol + ", Price: " + data.price);
}
var url = “ticker.js”; // URL of the external script
// this shows dynamic script insertion
var script = document.createElement('script');
script.setAttribute('src', url);
// load the script
document.getElementsByTagName('head')[0].appendChild(script);
In this case the "ticket.js" url contains something like this:
var data = {symbol: 'Hi', price: 91.42};
Possibility two is you create a local (php, perl, ruby, whatever you use) script which proxies to the external JSON source.