Loading local JSON file with Safari Extension - xmlhttprequest

Trying to load JSON file with Safari Extension.
var xhr = new XMLHttpRequest();
xhr.open("GET", safari.extension.baseURI +'js/data.json', true);
It gives an error "Cross origin requests are only supported for HTTP."
For example it is possible with Chrome Extenison
var xhr = new XMLHttpRequest();
xhr.open("GET", chrome.extension.getURL('/js/data.json'), true);
There you need to specify it in manifest
"web_accessible_resources": ["/js/data.json"]
Is there a similar way in Safari?
EDIT
Found a solution
It is possible through Global page
global.html
function handleMessage(event) {
if (event.name === "requestParagraphs") {
var xhr = new XMLHttpRequest();
xhr.open("GET", safari.extension.baseURI + 'js/data.json', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var articlesJSON = JSON.parse(xhr.responseText);
event.target.page.dispatchMessage('paragraphs', articlesJSON);
}
};
xhr.send();
}
}
safari.application.addEventListener("message", handleMessage, false);
injected.js
function handleMessage(msgEvent) {
var messageName = msgEvent.name;
var messageData = msgEvent.message;
if (messageName === "paragraphs") {
// ...
}
}
safari.self.addEventListener("message", handleMessage, false); // Listen response
safari.self.tab.dispatchMessage('requestParagraphs'); // Call global page

Related

Shutdown Kodi with api (blackberry qml)

Hello I trying shutdown Kodi (raspberry pi) with mobile app (blackberry qml).
But I do not how.
I used this code: (in browser)
"http://[myip]:[myport]/jsonrpc?request={"jsonrpc":"2.0","method":"System.Suspend","id":1}"
I used this code: (in the app)
function sendRequest() {
var xhr = new XMLHttpRequest();
var url = "http://[myip]:[myport]/jsonrpc?request={\"jsonrpc\":\"2.0\",\"method\": \"System.Suspend\",\"id\":1}"
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
console.log(xhr.responseText);
textArea.text = xhr.responseText;
}
}
};
xhr.open("GET", url, true); // with "POST" I got the same problem.
xhr.send();
}
I got:
{"error":{"code":-32700,"message":"Parse error."},"id":null,"jsonrpc":"2.0"}
Remote from web browser works fine (http://[myip]:[myport])
Thank you for your answers.
********** Update: 21.10.2020 **********
I'm in progress. But I don't know what to do next.
I found some information why I have an error.
I don't know how to implement in my code.
Can you help me?
Thank you so much.
https://github.com/xbmc/xbmc/pull/12281
https://forum.kodi.tv/showthread.php?tid=324598&highlight=json
Here's how to do it.But I can't understand it.
https://retifrav.github.io/blog/2018/09/01/kodi-remote-control-app/
This is my function (on Kodi 17.6 it is working but on Kodi 18 is not working )
function sendRequest() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
text.text = xhr.responseText
}
}
};
var url = 'http://<IP:PORT>/jsonrpc?request={"jsonrpc": "2.0", "id": 1, "method": "System.Shutdown"}'
xhr.open("GET", url, true) // when I write "POST" - nothing happens
xhr.send()
}
You should URL encode the json in your url before it's used in the open method. Use encodeURIComponent() to do that. Your browser is changing:
{"jsonrpc":"2.0","method": "System.Suspend","id":1}"
To:
%7B%22jsonrpc%22%3A%222.0%22%2C%22method%22%3A%20%22System.Suspend%22%2C%22id%22%3A1%7D%22
But your code is not.

trying to call api through xhr in Vuejs ,using promise to store response ,doesnt recognize .then()

I am trying to call api through xhr ,since axios is not working,how do i store response in a variable ,if i use promise .then() it throws error ,Below is what i am trying to do
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com', true).then(response=>{
console.log(response);
})
xhr.send();
error ,cannot read then
i got the answer.it works!!
xhr.onreadystatechange = function() {
var status;
var data;
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
if (xhr.readyState == 4) { // `DONE`
status = xhr.status;
if (status == 200) {
data = JSON.parse(xhr.responseText);
successHandler && successHandler(data);
} else {
errorHandler && errorHandler(status);
}
}
};

Express res.send not working

I have defined a variable so that I can store my endpoint in my express server.js file and I send it over a route called '/config' as shown below:
var webService,appConfig;
webService = "some endpoint";
appConfig = {
webServiceUrl: webService
};
app.get('/config', function(req, res) {
res.send(appConfig);
});
However, when I set up my http request like so:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
var
isReady = (xhr.readyState === 4),
isSuccess = (xhr.status === 200),
config;
if (isReady && isSuccess) {
config = JSON.parse(xhr.responseText);
window._configUrl = config;
}
}
xhr.open('GET', '/config', true);
xhr.send();
...it seems that the request is sending the index file instead of the variable I have defined. I have no idea why this would be happening. Any thoughts?

Slice ArrayBuffer with Safari and play it

I need to load a mp3, slice and play it using web audio , on firefox a slice mp3 any where and decode work fine, but on safari an error with null value occurs. Exist a trick or a way do slice the ArrayBuffer on Safari?
player.loadMp3 = function(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
var mp3slice = request.response.slice(1000,100000);
player.context.decodeAudioData(mp3slice); // context is webkitAudioContext on safari
callback();
};
request.send();
};
I need to create a mp3 player with some especial features:
Time shift the music (like http://codepen.io/eranshapira/pen/mnuoB)
Remove gap between musics ( I got this slicing ArrayBuffers and join then with a Blob but only in safary/IPAD don't work).
Cross platform (IPAD and android. I'm using apache cordova for that).
Solution
player.loadMp3 = function(url, callback) {
console.log("loading " + url);
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
console.log("loaded");
console.log("decoding...");
player.context.decodeAudioData(request.response, function(buffer) {
console.log("decoded");
player.buffer = player.joinAudioBuffers(player.buffer,buffer,2000000);
player.duration += player.buffer.duration;
player.time = minsSecs(player.buffer.duration);
console.log("concatenated");
callback();
});
}, function() {
alert("decode failure");
};
request.send();
};
The code you've shown shouldn't work on any browser. For one thing you need to provide a callback function to decodeAudioData. You also need to slice the decoded data after decoding it, not the raw mp3-encoded data before decoding it. Some browsers might be able to decode a slice of the mp3 file, but it's not expected. Something like this:
player.loadMp3 = function(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
var mp3slice = request.response.slice(1000,100000);
player.context.decodeAudioData(mp3slice, function(decoded) {
var pcmSlice = decoded.slice(1000, 100000);
callback(pcmSlice);
});
};
request.send();
};
I haven't tested this code.

angularjs post file to web api

I've a angular function for to upload file to web api
$scope.uploadFile = function () {
var file = $scope.file;
console.log("file: " + file);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", uri);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.setRequestHeader("X-File-Type", file.type);
$scope.progressVisible = true;
xhr.send(file);
}
function uploadProgress(evt) {
$scope.$apply(function () {
if (evt.lengthComputable) {
$scope.progress = Math.round(evt.loaded * 100 / evt.total);
}
})
}
function uploadComplete(evt) {
/* This event is raised when the server send back a response */
alert(evt.target.responseText);
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
function uploadCanceled(evt) {
$scope.$apply(function () {
$scope.progressVisible = false;
})
alert("The upload has been canceled by the user or the browser dropped the connection.");
}
The code is available here http://jsfiddle.net/vishalvasani/4hqVu/
I need a web api controller to manage file post, how can I read it?
Is it possible to use PostValue instead of task async?
Server side I get the file, read content, query a database and return JSON response
Thanks