I have a firefox extension that requests different APIs via XMLHttpRequest. However, the facebook like/share/comment count request leads to a logout in some online shops and some websites.
For example, GMX webmail has to restore the session after every click. Some online-shops seems to loose the session completeley so that there is an empty basket.
The problem only occurs with the facebook request enabled.
Request URL
http://api.facebook.com/method/fql.query?query=SELECT%20normalized_url,%20share_count,%20like_count,%20comment_count,%20click_count,%20total_count%20FROM%20link_stat%20WHERE%20url=%22www.heise.de%22&format=JSON
Javascript Code for the Request
var querystring = facebookURL + encodedUrl + facebookURLParams; // looks like the above
var mFacebookRequest = new XMLHttpRequest();
mFacebookRequest.onload = parseFacebookResponse;
mFacebookRequest.open( "GET", querystring );
// already tried without user-agent
mFacebookRequest.setRequestHeader( "User-Agent", "Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)" );
parseFacebookResponse function
function parseFacebookResponse() {
var fbcount = "-";
var share_count = 0;
var like_count = 0;
var comment_count = 0;
var aDoc = mFacebookRequest.responseText;
if( aDoc == null || aDoc == -1 || aDoc.length == 0 )
{
} else {
var jsonDoc = JSON.parse( aDoc );
var temp = jsonDoc[0];
share_count = parseInt(temp['share_count']);
like_count = parseInt(temp['like_count']);
comment_count = parseInt(temp['comment_count']);
}
The code is working perfectly and the numbers are displayed. But it keeps me logging out. Any idea?!
you are making a cross domain XML HTTP request. This coupled with the possibility that the GMX website is setting an immediately expiring session cookie -- your session is killed. This is just a hypothesis.
Related
<script>
function voice(){
var recognition = new webkitSpeechRecognition();
recognition.lang = "en-GB";
recognition.onresult = function(event){
console.log(event);
document.getElementById("speechto").value = event.results[0][0].transcript;
}
recognition.start();
}
</script>
I am making language translator web-app. And in above code, it takes input from the user using mic and print that in textarea in eng language. So I want this text in my python so that I can translate it and print it on another textarea. But i dont know how can I get that text from the js into my python code.
any soln?
Where is "your python"? I'm assuming this is on a browser over a network. You gotta set up a webserver (in python) to listen to network responses. Try webpy for a simple solution: https://webpy.org/.
You'll have to set up a URL endpoint to respond to POST requests. More info here: https://webpy.org/docs/0.3/tutorial#getpost.
And lastly, you'll have to set up your Javascript to send the post request and to use the response from your server to edit the textarea. You can use the JS fetch API to send the post request and handle the response from there.
Good luck hooking everything up
I assume you're using flask as that is tagged in your question. You need to establish a route to execute your python code and run your flask app which should listen to some TCP port on your computer (by default flask seems to use port 5000).
Then on your js code you can use the fetch method to send the text to that port. For example:
fetch('http://locahost:5000/{your flask route goes here}', {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
},
body: {text you want to send goes here},
})
rather than using python just to do a translation, why not to use a simple javascript translate function?
var translate = async (t,src,dst) => {
var tt = new Promise(function(resolve) {
var i=0, len=0, r='', tt='';
const url = 'https://clients5.google.com/translate_a/';
var params = 'single?dj=1&dt=t&dt=sp&dt=ld&dt=bd&client=dict-chrome-ex&sl='+src+'&tl='+dst+'&q='+t;
var xmlHttp = new XMLHttpRequest();
var response;
xmlHttp.onreadystatechange = function(event) {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
response = JSON.parse(xmlHttp.responseText);
for (var i = 0, len = response.sentences?.length; i < len; i++) {
var r=(((response.sentences[i].trans).replace('}/g','')).replace(')/g','')).replace('\%20/g', ' ');
r=((r.replace('}','')).replace(')','')).replace('\%20/g', ' ');
tt += r;
}
if (tt.includes('}'||')'||'%20')) {
tt=((tt.replace('}/g','')).replace(')/g','')).replace('\%20/g', ' ');
}
resolve(tt);
}
}
xmlHttp.open('GET', url+params, true);
xmlHttp.send(null);
xmlHttp.onreadystatechange();
});
return await tt;
}
I wasn't in charge of the Apache configuration, so I'm not sure what I can provide in terms of useful conf text, but I'm fairly certain I have narrowed the problem down to the login. EventSource works flawlessly both locally on XAMPP without any login and once you refresh the page after authenticating on the production server, but that first load on the server just will not open a connection. Has anyone seen this problem before? I couldn't find anything on the internet about this after searching for the past few days.
Edit: Some code
Some of the server-side code (which mostly shouldn't be relevant):
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$client_stream = new RedisStream();
$client_stream->poll(1); //The loop, with sleep time as a parameter
The JavaScript:
var xhttpViewSet;
var xhttpSearch;
var view = 'tile';
var search = '';
var seed_url = '/core/seed_view.php';
var stream_url = '/core/stream.php';
var default_class = 'panel-default';
var success_class = 'panel-success';
var warning_class = 'panel-warning';
var danger_class = 'panel-danger';
function UpdateClient(c_name, c_obj) {
if ((c_element = document.getElementById(c_name)) !== null) {
c_element.classList.remove('text-muted');
c_element.classList.remove(default_class);
c_element.classList.remove(success_class);
c_element.classList.remove(warning_class);
c_element.classList.remove(danger_class);
switch (c_obj['status']) {
case 0:
c_obj['status'] = 'OK';
c_element.classList.add(success_class)
break;
case 1:
c_obj['status'] = 'Warning';
c_element.classList.add(warning_class)
break;
case 2:
c_obj['status'] = 'Critical';
c_element.classList.add(danger_class)
break;
default:
c_obj['status'] = 'Unknown';
c_element.classList.add(danger_class)
break;
}
for (i in c_obj) {
var var_nodes = c_element.getElementsByClassName(i);
if (var_nodes.length > 0) {
for (var j = var_nodes.length - 1; j >= 0; j--) {
var_nodes[j].innerHTML = c_obj[i];
}
}
}
}
}
function SetView() {
var view_url = seed_url + '?search=' + search + '&view=' + view;
xhttpViewSet.open('GET', view_url, true);
xhttpViewSet.send();
}
var main = function() {
container = document.getElementById('content');
if (new XMLHttpRequest()) {
xhttpViewSet = new XMLHttpRequest();
xhttpSearch = new XMLHttpRequest();
} else {
xhttpViewSet = new ActiveXObject('Microsoft.XMLHTTP');
xhttpSearch = new ActiveXObject('Microsoft.XMLHTTP');
}
var stream = new EventSource(stream_url);
stream.onopen = function() {
console.log('Connection opened.'); //This doesn't fire
}
stream.onmessage = function(e) {
var c_obj = JSON.parse(e.data);
UpdateClient(c_obj.name, c_obj.value);
};
xhttpViewSet.onreadystatechange = function() {
if (xhttpViewSet.readyState == 4) {
var resp = xhttpViewSet.responseText;
if (xhttpViewSet.status == 200 && resp.length > 0) {
container.innerHTML = resp;
if (view == 'list') {
$('#computer-table').DataTable({
"lengthMenu": [[25, 50, 100], [25, 50, 100]]
});
}
} else {
container.innerHTML = '<error>No computers matched your search or an error occured.</error>';
}
}
}
SetView(); //This successfully does all but make the EventSource connection, and only fails to do that on first load
document.getElementById('list-view').addEventListener('click', function() {
view = 'list';
SetView();
});
document.getElementById('tile-view').addEventListener('click', function() {
view = 'tile';
SetView();
});
document.getElementById('search').addEventListener('keyup', function() {
search = this.value.toUpperCase();
SetView();
});
document.getElementById('clear-search').addEventListener('click', function() {
document.getElementById('search').value = '';
search = '';
SetView();
});
};
window.onload = main;
It is a bit hard to know for sure without a lot more information, but based on what you have said so far, I think it is one of:
HEAD/OPTIONS: Some browsers will send a HEAD or OPTIONS http call to a server script, before they send the GET or POST. The purpose of sending OPTIONS is to ask what headers are allowed to be sent. It is possible this is happening as part of the login process; that might explain why it works when you reload. See chapter 9 of Data Push Apps with HTML5 SSE (disclaimer: my book) for more details; basically, at the top of your SSE script you need to check the value of $_SERVER["REQUEST_METHOD"] and if it is "OPTIONS", intercept and say what headers you want to accept. I've used this one before:
header("Access-Control-Allow-Headers: Last-Event-ID,".
" Origin, X-Requested-With, Content-Type, Accept,".
" Authorization");`
CORS: The HTML page URL and the SSE page URL must have identical origins. There are detailed explanations (specific to SSE) in chapter 9 of Data Push Apps with HTML5 SSE (again), or (less specifically) at Wikipedia. If this is the problem, look into adding header("Access-Control-Allow-Origin: *"); to your SSE script.
withCredentials: There is a second parameter to the SSE constructor, and you use it like this: var stream = new EventSource(stream_url, { withCredentials: true }); It is saying it is okay to send the auth credentials. (Again, chapter 9 of the book goes into more detail - sorry for the repeated plugs!) There is a second step, over on the server-side: at the top of your PHP SSE script you need to add the following.
header("Access-Control-Allow-Origin: ".#$_SERVER["HTTP_ORIGIN"]);
header("Access-Control-Allow-Credentials: true");
PHP Sessions locking: This normally causes the opposite problem, which is that the SSE script has locked the PHP session, so no other PHP scripts work. See https://stackoverflow.com/a/30878764/841830 for how to handle it. (It is a good idea to do this anyway, even if it isn't your problem.)
I'm trying to add a user who clicks on a button in a SharePoint (online) site to a Office 365 group. I know this can be done via JSON using the Add Member API.
https://github.com/OfficeDev/microsoft-graph-docs/blob/master/api-reference/v1.0/api/group_post_members.md
I am however really inexperienced when it comes to JSON and keep messing up the POST function. This is the code I have currently, everything before the comma has been working fine.
function showButton() {
$('btn-1').on('click', function(event) {
var userProfileProperties
var clientContext = new SP.ClientContext.get_current();
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);
userProfileProperties = peopleManager.getMyProperties();
clientContext.load(userProfileProperties);
clientContext.executeQueryAsync(onSuccess, onFail);
function onSuccess(){
accountProperties = userProfileProperties.get_userProfileProperties();
accountId = accountProperties['msOnline-ObjectId'];
//JSON Query
jQuery.ajax({
url: "https://mysite.sharepoint.com/groups/groupID/members/$ref";
method: "POST";
contentType: "application/json";
dataType: 'json',
{
"#odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/" + accountId
};
});
};
function onFail(){
alert(failed);
};
});
};
In your document , you will find authentication token is required in the Request headers .Without authentication token ,you will receive an error as :
"code": "InvalidAuthenticationToken", "message": "Bearer access token is empty."
As a solution , you could try following steps :
1.Register a javascript Application in Azure AD and configure your app to allow the OAuth 2.0 implicit grant flow.Tokens are obtained using the OAuth 2.0 implicit grant flow. Using implicit grant, your application requests an access token from Azure AD for the currently signed-in user by sending the user to an authorization URL where the user signs in with their Office 365 credentials and then is redirected back to the app with the access token in the URL .
2.Add permissions to Graph API .
3.Add an html page to your sharepoint online(using Explorer mode) .
4.Edit the html , write below function to get an access token:
function requestToken() {
// Change clientId and replyUrl to reflect your app's values
// found on the Configure tab in the Azure Management Portal.
// Also change {your_subdomain} to your subdomain for both endpointUrl and resource.
var clientId = '3dadb44e-feaa-4158-90f5-e129e15db66d';//ID of your App in Azure
var replyUrl = 'https://o365e3w15.sharepoint.com/sites/XXX/app.html'; //my sharepoint page that requests
//an oauth 2 authentification and data
//It is also referenced in the REPLY URL field of my App in Azure
var endpointUrl = 'https://graph.microsoft.com/v1.0/me/messages';
var resource = "https://graph.microsoft.com/";
var authServer = 'https://login.windows.net/common/oauth2/authorize?';
//var authServer = 'https://login.microsoftonline.com/common/oauth2/authorize?';//this works either
var responseType = 'token';
var url = authServer +
"response_type=" + encodeURI(responseType) + "&" +
"client_id=" + encodeURI(clientId) + "&" +
"resource=" + encodeURI(resource) + "&" +
"redirect_uri=" + encodeURI(replyUrl);
window.location = url;
}
After that ,you could make an ajax call to graph api endpoint to get/post request, for example, get current user's messages:
var endpointUrl = "https://graph.microsoft.com/v1.0/me/messages";
var xhr = new XMLHttpRequest();
xhr.open("GET", endpointUrl);
var myToken = getToken();
// The APIs require an OAuth access token in the Authorization header, formatted like this:
//'Authorization: Bearer <token>'.
xhr.setRequestHeader("Authorization", "Bearer " + myToken);
// Process the response from the API.
xhr.onload = function () {
if (xhr.status == 200) {
//alert('data received');
var message="";
var object = JSON.parse(xhr.response);
for(i=0;i<object.value.length;i++){
message+='Subject: ' + object.value[i].subject + '<br>';
}
document.getElementById("results").innerHTML = message;
} else { }
}
// Make request.
xhr.send();
display this app.html into any SharePoint Webpart page by calling it within an iframe tag.
All detail steps you will find in this article , i have tested and work fine in my side .
I'm building a chrome extension that needs to allow user authentication through facebook. I've been following the "manual login flow" since the facebook Javascript SDK doesn't work in extensions. Thus far, I've allowed users to click a link that gets permissions and returns an access token:
index.html
Sign In with Facebook
index.js
function onFacebookLogin(){
if (localStorage.getItem('accessToken')) {
chrome.tabs.query({}, function(tabs) { // get all tabs from every window
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].url.indexOf(successURL) !== -1) {
// below you get string like this: access_token=...&expires_in=...
var params = tabs[i].url.split('#')[1];
// in my extension I have used mootools method: parseQueryString. The following code is just an example ;)
var accessToken = params.split('&')[0];
accessToken = accessToken.split('=')[1];
localStorage.setItem('accessToken', accessToken);
chrome.tabs.remove(tabs[i].id);
console.log(accessToken)
userSignedIn = true
findFacebookName();
}
}
});
}
}
chrome.tabs.onUpdated.addListener(onFacebookLogin);
^ ALL OF THIS WORKS. Everytime a user "logs in" the localstorage.accessToken is updated. Then, I get to the point where I try to retrieve user data by inspecting the token through the api:
var client_token = '{MY_CLIENT_TOKEN(NOT CLIENT_ID}'
var inspectTokenUrl = 'https://graph.facebook.com/debug_token?input_token=' +
localStorage.accessToken +
'&access_token=' +
client_token
function findFacebookName(){
var xhr = new XMLHttpRequest();
xhr.open("GET", inspectTokenUrl, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
}
}
xhr.send();
}
But this returns a 190 oauth error. What am I doing wrong? What is the correct way to request the users email address using the access_token?
currently i using this code in phonegap application
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://192.168.1.19:8080/searchMobile?categoryRequest=true", true);
xmlhttp.send(null);
xmlhttp.onreadystatechange = function() {alert(xmlhttp.status);
if (xmlhttp.readyState == 4) {
var responseObject = eval("(" + xmlhttp.responseText + ")");
var results = responseObject.result;
if (results != null)
{
var resLength = results.length;
category.length = category.length + resLength;
for ( var i = 0; i < resLength; i++)
{
category.options[category.length - (resLength - i)].innerHTML = results[i].categoryName;
$(category).selectmenu("refresh");
}
}
}
this code is working in android but when i run this code on iphone it gives status 0 means doesn't work.
how can i overcome this problem
many thanks.
First as #Raymond Camden said make sure your url is white listed in the .plist. Second it is perfectly normal for you to get a status of 0 when doing AJAX from the file:// protocol. Webkit will set the status to 0 because you are doing a cross domain request which in a web browser would be blocked but in a web view, like PhoneGap uses, is perfectly okay. So in this case 0 == 200. Third get rid of eval, if you are returning JSON data use JSON.parse(xmlhttp.responseText) as it is much safer.
Try adding the URL to the whitelist.