toby
February 6, 2021, 12:38pm
1
Hi, I’m trying to use getURLParams() but get undefined, tested in Chrome and Firefox. Code below and online . Can anyone see what is wrong, please? thanks!
// test with p5.js Web Editor
// ref: reference | p5.js
function setup() {
createCanvas(400, 400);
noLoop();
}
function draw() {
let params = getURLParams();
console.log(params);
}
Hi,
My guess is that the p5 web editor is a sort of JavaScript container for your sketch. In fact it’s an iframe :
Here the srcdoc
attribute contains the actual code of the nested page :
srcdoc="<!DOCTYPE HTML>
<html lang="en"><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js" crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js" crossorigin=""></script>
<meta charset="utf-8">
<base href="https://editor.p5js.org/tobyhoward/sketches/TJeGFhQys?year=2014&month=May&day=15/"><style>
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
</style><script src="/previewScripts.js"></script><script>
function getScriptOff(line) {
var offs = [[70,"sketch"]];
var l = 0;
var file = '';
for (var i=0; i<offs.length; i++) {
var n = offs[i][0];
if (n < line && n > l) {
l = n;
file = offs[i][1];
}
}
return [line - l, file];
}
// catch reference errors, via http://stackoverflow.com/a/12747364/2994108
window.onerror = function (msg, url, lineNumber, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
var data = {};
if (url.match(/^(http:\/\/|https:\/\/)/) !== null && error.stack){
var errorNum = error.stack.split('about:srcdoc:')[1].split(':')[0];
var fileInfo = getScriptOff(errorNum);
data = msg + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')';
} else {
var fileInfo = getScriptOff(lineNumber);
data = msg + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')';
}
window.parent.postMessage([{
log: [{
method: 'error',
data: [data],
id: Date.now().toString()
}],
source: fileInfo[1]
}], '*');
return false;
};
// catch rejected promises
window.onunhandledrejection = function (event) {
if (event.reason && event.reason.message && event.reason.stack){
var errorNum = event.reason.stack.split('about:srcdoc:')[1].split(':')[0];
var fileInfo = getScriptOff(errorNum);
var data = event.reason.message + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')';
window.parent.postMessage([{
log: [{
method: 'error',
data: [data],
id: Date.now().toString()
}],
source: fileInfo[1]
}], '*');
}
};
</script></head>
<body>
<script data-tag="@fs-sketch.js">// test with https://editor.p5js.org/tobyhoward/sketches/TJeGFhQys?day=1&month=Feb&year=1977
// ref: https://p5js.org/reference/#/p5/getURLParams
function setup() {
createCanvas(400, 400);
noLoop();
}
function draw() {
let params = getURLParams();
console.log(params);
console.log(location.href);
}</script>
</body></html>"
And in the source code of p5, we can see that it uses location.search
to extract the url parameters :
p5.prototype.getURLParams = function() {
const re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;
let m;
const v = {};
while ((m = re.exec(location.search)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
v[m[1]] = m[2];
}
return v;
};
In the p5 web editor, printing location.search
gives this :
""
It doesn’t work because an iframe is literally a page contained in another one. So it has it’s own url (tested in the web editor) :
console.log(location.href); // -> about:srcdoc
But using getURLParams()
on a local page works fine!
2 Likes
toby
February 7, 2021, 9:20am
3
Thank you very much josephh for taking the time to look at that! I now notice that if you share the sketch as “present” or “fullscreen” then getURLParams() does work correctly. It is just in the editor that it does not, as you explain. It think it would be helpful to add a note about this behaviour to the getURLParams() ref page. I’ll pursue that.
best,
Toby
1 Like