when using C3 library, csv file couldn't be loaded - csv

I tried this sample code, but csv file can't be read.
I put the csv file in the exact location. (same with the directory of index.html)!
Not with csv file (with array data), it perfectly works.
Has the grammar rule changed or is there a mistake in the code?
If anyone can check if this code works or can help me anyhow, It'll be really appreciated.
var chart = c3.generate({
data: {
url: '/data/c3_test.csv',
type: 'line'
}
});
setTimeout(function () {
chart.load({
url: '/data/c3_test2.csv'
});
}, 1000);
setTimeout(function () {
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160, 150],
['data4', 30, 20, 50, 40, 60, 50],
],
unload: ['data2', 'data3'],
});
}, 2000);
setTimeout(function () {
chart.load({
rows: [
['data2', 'data3'],
[120, 300],
[160, 240],
[200, 290],
[160, 230],
[130, 300],
[220, 320],
],
unload: 'data4',
});
}, 3000);

Maybe you are loading the model using either file:// or C:/, which stays true to the error message as they are not http://.
You can confirm that this is the error message that you're getting on your browser's console. But I did what you asked and I got the "Fetch API cannot load file:///C:/data.csv. URL scheme must be "http" or "https" for CORS request." and the csv file could not be loaded either.
So you can either install a webserver in your local PC or upload the model somewhere else and change the url to http://somehost/path/to/file
As an alternative, If you're using Chrome, you can try starting it from the terminal with the --allow-file-access-from-files
Browsers don't allow file:// URLs with ajax calls (for security reasons). You need to load your web page through a web server and make your ajax request through that web server using http:// or https://, not file://

Related

can make extinction chrome work automatically when open chrome [duplicate]

I'm writing a Chrome extension and trying to overlay a <div> over the current webpage as soon as a button is clicked in the popup.html file.
When I access the document.body.insertBefore method from within popup.html it overlays the <div> on the popup, rather than the current webpage.
Do I have to use messaging between background.html and popup.html in order to access the web page's DOM? I would like to do everything in popup.html, and to use jQuery too, if possible.
ManifestV3 service worker doesn't have any DOM/document/window.
ManifestV3/V2 extension pages (and the scripts inside) have their own DOM, document, window, and a chrome-extension:// URL (use devtools for that part of the extension to inspect it).
You need a content script to access DOM of web pages and interact with a tab's contents. Content scripts will execute in the tab as a part of that page, not as a part of the extension, so don't load your content script(s) in the extension page, use the following methods:
Method 1. Declarative
manifest.json:
"content_scripts": [{
"matches": ["*://*.example.com/*"],
"js": ["contentScript.js"]
}],
It will run once when the page loads. After that happens, use messaging but note, it can't send DOM elements, Map, Set, ArrayBuffer, classes, functions, and so on - it can only send JSON-compatible simple objects and types so you'll need to manually extract the required data and pass it as a simple array or object.
Method 2. Programmatic
ManifestV2:
Use chrome.tabs.executeScript in the extension script (like the popup or background) to inject a content script into a tab on demand.
The callback of this method receives results of the last expression in the content script so it can be used to extract data which must be JSON-compatible, see method 1 note above.
Required permissions in manifest.json:
Best case: "activeTab", suitable for a response to a user action (usually a click on the extension icon in the toolbar). Doesn't show a permission warning when installing the extension.
Usual: "*://*.example.com/" plus any other sites you want.
Worst case: "<all_urls>" or "*://*/", "http://*/", "https://*/" - when submitting into Chrome Web Store all of these put your extension in a super slow review queue because of broad host permissions.
ManifestV3 differences to the above:
Use chrome.scripting.executeScript.
Required permissions in manifest.json:
"scripting" - mandatory
"activeTab" - ideal scenario, see notes for ManifestV2 above.
If ideal scenario is impossible add the allowed sites to host_permissions in manifest.json.
Some examples of the extension popup script that use programmatic injection to add that div.
ManifestV3
Don't forget to add the permissions in manifest.json, see the other answer for more info.
Simple call:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: inContent1,
});
})();
// executeScript runs this code inside the tab
function inContent1() {
const el = document.createElement('div');
el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red';
el.textContent = 'DIV';
document.body.appendChild(el);
}
Note: in Chrome 91 or older func: should be function:.
Calling with parameters and receiving a result
Requires Chrome 92 as it implemented args.
Example 1:
res = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: (a, b) => { return [window[a], window[b]]; },
args: ['foo', 'bar'],
});
Example 2:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
let res;
try {
res = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: inContent2,
args: [{ foo: 'bar' }], // arguments must be JSON-serializable
});
} catch (e) {
console.warn(e.message || e);
return;
}
// res[0] contains results for the main page of the tab
document.body.textContent = JSON.stringify(res[0].result);
})();
// executeScript runs this code inside the tab
function inContent2(params) {
const el = document.createElement('div');
el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red';
el.textContent = params.foo;
document.body.appendChild(el);
return {
success: true,
html: document.body.innerHTML,
};
}
ManifestV2
Simple call:
// uses inContent1 from ManifestV3 example above
chrome.tabs.executeScript({ code: `(${ inContent1 })()` });
Calling with parameters and receiving a result:
// uses inContent2 from ManifestV3 example above
chrome.tabs.executeScript({
code: `(${ inContent2 })(${ JSON.stringify({ foo: 'bar' }) })`
}, ([result] = []) => {
if (!chrome.runtime.lastError) {
console.log(result); // shown in devtools of the popup window
}
});
This example uses automatic conversion of inContent function's code to string, the benefit here is that IDE can apply syntax highlight and linting. The obvious drawback is that the browser wastes time to parse the code, but usually it's less than 1 millisecond thus negligible.

How to record http requests with Google Chrome extension and persist them

I want to create a Chrome extension, that records HTTP requests (to a pre-defined host) and persists them as a list in local storage so when I call a particular website again the list will be extended.
I want to go with Manifest v3 to make the extension "ready for the future". I created a background script to trigger the request that currently puts all the details into local storage like that (currently this is redundant for demonstration purposes, I also tried it seperated):
chrome.webRequest.onBeforeRequest.addListener(details => {
var urls = [];
chrome.storage.local.get(['data'], function(data){
urls = data.urls;
});
chrome.scripting.executeScript(
{
target: {tabId: details.tabId},
func: recordClick,
args: [details, urls]
},
() => {
urls.push(details);
console.log(urls.length);
chrome.storage.local.set({urls: urls});
});
}, {
urls: ['<all_urls>']
});
There's another function called recordClick() that does the same as in the callback:
function recordClick(details, urls) {
urls.push(details.url);
chrome.storage.local.set({urls: urls});
}
I tried several ways on where to load and save the result but none of them work. When I load the previous urls within the onBeforeRequest trigger, urls is not global and not known within the callback. When I put it outside the trigger definition, it's not reading the storage in realtime. I also tried to load the urls in a content script, loaded at "Document start". I tried to load the urls in the backend script at the top, and so on.
Seems like I have a timing problem: The trigger always loads an empty list or the variable is not global. I'm not able to extend the list. No matter where I put the storage functions.
Is my plan feasable at all? What am I'm doing wrong?
thanks!
Since chrome.storage.local.get is asynchronous, you should move chrome.scripting.executeScript into the callback of it.
onComplete may be suitable for your purpose, instead of onBeforeRequest.
chrome.webRequest.onBeforeRequest.addListener(details => {
chrome.storage.local.get('urls', function(data){
let urls = [];
if( data.urls ) {
urls = data.urls;
}
urls.push(details);
chrome.storage.local.set({urls: urls}, function() {
console.log('Value is set to ');
console.log(urls);
});
chrome.scripting.executeScript( {
target: {tabId: details.tabId},
func: function(details, urls){ console.log("executed script") },
args: [details, urls]
},
() => {
console.log("injected")
});
});
},
{ urls: ['<all_urls>'] }
);

How to save websocket frames in Chrome

I am logging websocket traffic using Chrome/Developer Tools. I have no problem to view the websocket frames in network "Frames" window, but I can not save all frames (content enc. as JSON) in an external (text) file.
I have already tried save as HAR and also simply used cntl A,C,V (first "page" copied only) but have so far not been very successful.
I am running Linux Mint 17.
Do you have hints how this can be done?
From Chrome 76 the HAR file now includes WebSocket messages.
WebSocket messages in HAR exports
The _webSocketMessages property begins with an underscore to indicate that it's a custom field.
...
"_webSocketMessages": [
{
"type": "send",
"time": 1558730482.5071473,
"opcode": 1,
"data": "Hello, WebSockets!"
},
{
"type": "receive",
"time": 1558730482.5883863,
"opcode": 1,
"data": "Hello, WebSockets!"
}
]
...
Update for Chrome 63, January 2018
I managed to export them as JSON as this:
detach an active inspector (if necessary)
start an inspector on the inspector with ctrl-shift-j/cmd-opt-j
paste the following code into that inspector instance.
At this point, you can do whatever you want with the frames. I used the console.save utility from https://bgrins.github.io/devtools-snippets/#console-save to save the frames as a JSON file (included in the snippet below).
// https://bgrins.github.io/devtools-snippets/#console-save
(function(console){
console.save = function(data, filename){
if(!data) {
console.error('Console.save: No data')
return;
}
if(!filename) filename = 'console.json'
if(typeof data === "object"){
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
})(console)
// Frame/Socket message counter + filename
var iter = 0;
// This replaces the browser's `webSocketFrameReceived` code with the original code
// and adds two lines, one to save the socket message and one to increment the counter.
SDK.NetworkDispatcher.prototype.webSocketFrameReceived = function (requestId, time, response) {
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) return;
console.save(JSON.parse(response.payloadData), iter + ".json")
iter++;
networkRequest.addFrame(response, time, false);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
}
This will save all incoming socket frames to your default download location.
This is something that is not possible to put into HAR format at this
time because HAR specification does not have details on how to export
framed transfer formats like WebSockets
From here: https://groups.google.com/forum/#!topic/google-chrome-developer-tools/jUOLFqpu-2Y
There is an open request for this feature
https://bugs.chromium.org/p/chromium/issues/detail?id=496006
please "star" it to raise the priority.

RTCPeerConnection media stream working in firefox but not chrome

Trying to keep the problem as simple as possible, I am creating a media stream in a chrome extension like so:
var pc = new RTCPeerConnection(null);
chrome.desktopCapture.chooseDesktopMedia(['screen', 'window'], null, function(streamId) {
var constraints = {
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: streamId
}
}
},
success = function(stream) {
pc.addStream(stream);
pc.createOffer(function(offer) {
pc.setLocalDescription(offer, function() {
send('make_offer', name, offer);
}, printError);
}, printError);
};
getUserMedia(constraints, success, printError);
});
For now, my offer is received by a peer visiting a page in a browser. That looks more or less like this (m is a message object with the offer):
var pc = new RTCPeerConnection(null);
pc.onaddstream = function(e) {
var video = document.getElementById('video');
video.src = URL.createObjectURL(e.stream);
};
pc.setRemoteDescription(new RTCSessionDescription(m.value), function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer, function() {
send('make_answer', m.from, answer);
}, printError);
}, printError);
}, printError);
I have done this, both with and without ice servers, which look like this when I use them:
var iceServers = {
iceServers: [
{url: 'stun:stun.l.google.com:19302'}
]
};
Right now, the peer receives and displays the stream perfectly in Firefox. No problem at all. But it's not working in Chrome. Here is some selected data from chrome://webrtc-internals:
connection to firefox:
"ssrc_3309930214_send-transportId": {
"startTime": "2014-09-30T01:41:11.525Z",
"endTime": "2014-09-30T01:41:21.606Z",
"values": "[\"Channel-video-1\",\"Channel-video-1\",\"Channel-video-1\"]"
},
"ssrc_3309930214_send-packetsLost": {
"startTime": "2014-09-30T01:41:11.525Z",
"endTime": "2014-09-30T01:41:21.606Z",
"values": "[0,0,0,0,0,0,0]"
},
connection to chrome:
"ssrc_1684026093_send-transportId": {
"startTime": "2014-09-30T01:41:57.310Z",
"endTime": "2014-09-30T01:42:00.313Z",
"values": "[\"Channel-audio-1\",\"Channel-audio-1\",\"Channel-audio-1\",\"Channel-audio-1\"]"
},
"ssrc_1684026093_send-packetsLost": {
"startTime": "2014-09-30T01:41:57.310Z",
"endTime": "2014-09-30T01:42:00.313Z",
"values": "[-1,-1,-1,-1]" // what is causing this??
},
Those seem important, but I'm not sure exactly of the implications. I have more data, but I'm not sure exactly what is important. The main idea, is that data goes out to firefox, but not to chrome, though no exceptions occur that I can see. The one further suspicious piece of data happens if I load the peer page in Chrome Canary (latest):
Failed to load resource: net::ERR_CACHE_MISS
This is a console error, and I don't know where it comes from. It occurs after the answer is sent from the peer back to the host (chrome extension).
Signaling done over wss://, test peer is hosted at https://
I'm not sure where to go from here.
Update: Based on answer and comment, I added a handler for onicecandidate:
pc.onicecandidate = function(e) {
console.log('This is the ice candidate.');
console.log(e);
if(!e.candidate) return console.warn('no candidate!');
send('got_ice_candidate', name, e.candidate);
};
I also set up an equivalent peer connection from browser to browser using video:
var constraints = {
audio: false,
video: true
};
getUserMedia(constraints, success, printError);
This works fine, both from Firefox to Chrome and vise-versa, so the issue may be chrome-extension-specific...
There is a difference in how ice gathering occurs between the successful case and the extension case:
Between browsers, there is no ice at all. There is one event, and e.candidate is null.
From extension to browser, there are lots of onicecandidate events. They are not all in agreement. So perhaps the chrome extension is confusing the STUN server? I don't know.
Thanks for your answers, would love any more insight that you have.
can you please add handling ice candidates on both sides ?
pc.onicecandidate = function(e){ send('ice_candidate', e.target) }
And on the other side on receiving this 'message' do
pc.addIceCandidate(new RTCIceCandidate(message));
Chrome sends ice candidates even after offer/answer have been exchanged which firefox does not seem to do.

In Google Chrome, what is the extension api for changing the UserAgent and Device Metrics?

In Google Chrome, when viewing the developer tools, in the bottom right there is a Gear Icon that opens an additional Settings popup. One of the pages in the Settings popup is Overrides that contains User Agent and Device Metrics settings. I am trying to find the extensions API that is able to set those values programatically. Does such an API exist?
I've looked the main apis, and the experimental apis , but can't seem to find anything.
The sample for devtools.panels in the code samples doesn't seem to indicate how to 'explore' the existing devpanels either.
Specifically I'm trying to build simple extension available from a context menu in a Browser Action. It would act like a user-agent switcher, offering choices from the same list in the Settings popup, and automatically sets the Device Metrics to the values of the selected Agent. e.g. 640x960 for IPhone 4.
Any leads on how to programatically access the Settings popup
Some of the advanced features offered by the Developer tools can be accessed through the chrome.debugger API (add the debugger permission to the manifest file).
The User agent can be changed using the Network.setUserAgentOverride command:
// Assume: tabId is the ID of the tab whose UA you want to change
// It can be obtained via several APIs, including but not limited to
// chrome.tabs, chrome.pageAction, chrome.browserAction, ...
// 1. Attach the debugger
var protocolVersion = '1.0';
chrome.debugger.attach({
tabId: tabId
}, protocolVersion, function() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
return;
}
// 2. Debugger attached, now prepare for modifying the UA
chrome.debugger.sendCommand({
tabId: tabId
}, "Network.enable", {}, function(response) {
// Possible response: response.id / response.error
// 3. Change the User Agent string!
chrome.debugger.sendCommand({
tabId: tabId
}, "Network.setUserAgentOverride", {
userAgent: 'Whatever you want'
}, function(response) {
// Possible response: response.id / response.error
// 4. Now detach the debugger (this restores the UA string).
chrome.debugger.detach({tabId: tabId});
});
});
});
The official documentation for the supported protocols and commands can be found here. As of writing, there's no documentation for changing the Device metrics. However, after digging in Chromium's source code, I discovered a file which defined all currently known commands:
chromium/src/out/Debug/obj/gen/webcore/InspectorBackendDispatcher.cpp
When I look through the list of definitions, I find Page.setDeviceMetricsOverride. This phrase seems to match our expectations, so let's search further, to find out how to use it:
Chromium code search: "Page.setDeviceMetricsOverride"
This yields "chromium/src/out/Release/obj/gen/devtools/DevTools.js" (thousands of lines). Somewhere, there's a line defining (beautified):
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{
"name": "width",
"type": "number",
"optional": false
}, {
"name": "height",
"type": "number",
"optional": false
}, {
"name": "fontScaleFactor",
"type": "number",
"optional": false
}, {
"name": "fitWindow",
"type": "boolean",
"optional": false
}], []);
How to read this? Well, use your imagination:
chrome.debugger.sendCommand({
tabId: tabId
}, "Page.setDeviceMetricsOverride",{
width: 1000,
height: 1000,
fontScaleFactor: 1,
fitWindow: false
}, function(response) {
// ...
});
I've tested this in Chrome 25 using protocol version 1.0, and it works: The tab being debugged is resized. Yay!