some wms or wfs sources require user and password authentication.
for example https://apps.sogelink.fr/maplink/public/wfs?request=GetCapabilities
need Basic authentication.
How can I inject this authentication?
You can provide your own imageLoadFunction to an ImageWMS source.
The default one just takes the URL and inserts it as the src of the img tag:
ol.source.Image.defaultImageLoadFunction = function(image, src) {
image.getImage().src = src;
};
That question was already asked on the OpenLayers GitHub, here is an example from there:
function customLoader(tile, src) {
var client = new XMLHttpRequest();
client.open('GET', src);
client.setRequestHeader('foo', 'bar');
client.onload = function() {
var data = 'data:image/png;base64,' + btoa(unescape(encodeURIComponent(this.responseText));
tile.getImage().src = data;
};
client.send();
}
The documentation of OpenLayers is really good. Just find an example that uses features you want and then follow the links to the API docs.The ol.source.Vector doc even includes an example of a loading function for WFS, where you could manipulate the request:
new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
var wfsUrl = 'TODO';
var xhr = new XMLHttpRequest();
// see above example....
}
});
Related
Is there a way to fetch the number of contributions in the last year using Javascript (client-side)? Note that number is for the public and private repository
Use a GraphQL query (GitHub API v4) and a ContributionsCollection object.
Define from by now minus one year, and to by now.
var to = new Date();
var year = to.getFullYear();
var month = to.getMonth();
var day = to.getDate();
var from = new Date(year - 1, month, day);
Use graphql.js to then call, as in here:
query ContributionsView($username: String!, $from: DateTime!, $to: DateTime!) {
user(login: $username) {
contributionsCollection(from: $from, to: $to) {
totalCommitContributions
totalIssueContributions
totalPullRequestContributions
totalPullRequestReviewContributions
}
}
}
Once the script works outside your Blogger page, you can include it with a <script src=...> element.
I've tried many solutions and I improved one to get the following which works the best for me:
Create a function in Javascript
function get_contribution() {
profile_url = "https://cors-anywhere.herokuapp.com/https://github.com/users/USERNAME/contributions";
var xhr = new XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', profile_url, true);
xhr.onload = function () {
if (this.status == 200) {
var response = xhr.responseXML.getElementsByClassName('f4 text-normal mb-2')[0].innerText;
// get only the numbers in response
contribution = response.replace(/[^0-9]/g, '');
// The number of contributions is now saved in the contribution variable
}
};
xhr.send();
}
Change USERNAME to the GitHub username you want
Note that you have to use "cors" or it won't work
Now you can use that function anywhere but in my case, I will call it on page load and set it somewhere in the HTML:
onload = function(){
get_contribution();
}
I suggest using the unofficial Github Contributions API located at this site
Here is an example
async function getContributions(username) {
var data = await (await fetch(`https://corsanywhere.herokuapp.com/https://github-contributions-api.deno.dev/${username}.json`)).json();
console.log(data.totalContributions)
}
getContributions("octocat") // Returns 0, as Octocat has zero contributions
I need to get images from multiple WebMapServers (of my company) with Open Layers (and pure Javascript).
Basically it works. Problem is that some servers require HTTP Basic Auth. The OL documentation and a related SO question say that this should be done with a XMLHttpRequest inside an imageLoadFunction:
https://openlayers.org/en/latest/apidoc/module-ol_Image.html
How to assign basic authentication header to XMLHTTPREQUEST?
At first I want to get images with XMLHttpRequest and without Basic Auth:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Image({
source: new ol.source.ImageWMS({
ratio: 1,
params: { LAYERS: 'ENC', CSBOOL: '2083', CSVALUE: ',,,,,3'},
url: 'https://wms-without-basic-auth.com/?',
imageLoadFunction: function(image, src) {
image.getImage().src = src;
/*
var client = new XMLHttpRequest();
client.open('GET', src, true);
client.setRequestHeader( 'Content-Type', 'image/png' );
client.setRequestHeader( 'Accept', 'image/png' );
client.onload(function() {
image.getImage().src = src;
});
client.send();
*/
},
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([6,54]),
zoom: 6
})
});
The imageLoadFunction only works with the line
image.getImage().src = src;
but not with the commented XMLHttpRequest.
I think the loaded image must be assigned in the client.onload function, but I'm not sure how to do this.
So how should I use the XMLHttpRequest inside the imageLoadFunction?
From the docs:
Providing a custom imageLoadFunction can be useful to load images with post requests or - in general - through XHR requests, where the src of the image element would be set to a data URI when the content is loaded.
Maybe try something like this:
imageLoadFunction: function(image, src) {
var client = new XMLHttpRequest();
client.open('GET', src, true);
client.setRequestHeader( 'Content-Type', 'image/png' );
client.setRequestHeader( 'Accept', 'image/png' );
client.responseType = 'blob';
client.onload(function() {
const blob = new Blob(client.response);
const urlData = URL.createObjectURL(blob);
image.getImage().src = urlData;
});
client.send();
},
What it does:
gets your image from your server
Create a blob
Converts the blob to urlData
Finally uses the urlData as source for your image
I am building a webmapping app. I parse the WMS request to have the title of each layer in layers:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8082/geoserver/wms?service=wms&request=GetCapabilities', true);
xhr.onload = function() {
var parser = new ol.format.WMSCapabilities();
var capabilities = parser.read(xhr.responseText);
var layers = capabilities.Capability.Layer.Layer.Title;
};
But then I fail to access to the titles contain in layers:
$.each(layers, function(i)
{
var list = $('</br><a/>')
.text(layers[i])
.appendTo($('div.myDiv'));
});
What did I miss? Thanx for the help.
I think the problem is, that you need the Name of the Layer, not the Title to be able to call it.
So you would parse the capabilities like this:
var layers = capabilities.Capability.Layer.Layer.Name;
I need to embed a Flash .swf on the page and am unable use the normal way of setting the src or data attribute to the swf url - don't ask :s. So, I'm doing an ajax request for the swf, converting to a blob and then generating a blob url which I set as the swf src. Then I realised that as I'm building with Grunt, there may be a way to just write the swf file into the code as a blob in a var, and avoid the ajax request completely. Here's the code with the ajax request:
function createFlashMovie(blobUrl){
var obj = document.createElement("object");
obj.setAttribute("width", "800");
obj.setAttribute("height", "600");
obj.setAttribute("type", "application/x-shockwave-flash");
obj.setAttribute("data", blobUrl);
document.body.appendChild(obj);
}
function onAjaxLoad(oResponse){
blobUrl = window.URL.createObjectURL(oResponse);
createFlashMovie(blobUrl);
};
//do the xhr request for a.swf
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
onAjaxLoad(this.response);
}
}
xhr.open('GET', '//theserver.com/a.swf');
xhr.responseType = 'blob';
xhr.send();
...but I'm sure it must be possible to have something like this which is replaced by grunt to have the blob already available when it runs, and go straight to creating the blob url without the xhr request:
var theBlob = new Blob(["GRUNT_WRITES_THIS_IN_FROM_FILE"], {type: "application/x-shockwave-flash"});
Well, grunt is at its core just a Node program, so you can use any node command in your Gruntfile or tasks definitions. And it seems that Node's http.request would be perfect for your needs.
So:
add a custom task in your Gruntfile (http://gruntjs.com/creating-tasks#custom-tasks)
that uses http.request to download your swf (https://docs.nodejitsu.com/articles/HTTP/clients/how-to-create-a-HTTP-request)
update your code to use the local swf
I found a solution. Convert your swf file to be a base64-encoded string. At the moment I'm doing this separately and then pasting it into the source JS, but it can be automated at build time with grunt. Then in the page script create a var to store it as a dataURI:
var swfAsDataUri = "data:application/x-shockwave-flash;base64,BIG_LONG_CHUNK_OF_DATA_THAT_IS_YOUR_ENCODED_SWF_FILE__GRUNT_CAN_WRITE_THIS_IN_AT_BUILD_TIME";
Create a blob from the data url, and then create an object url from the blob:
//function taken from http://stackoverflow.com/questions/27159179/how-to-convert-blob-to-file-in-javascript
dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
};
var blobUrl = window.URL.createObjectURL( dataURLToBlob(swfAsDataUri) );
You can then use the object url as the src data for the flash movie's object tag when it's embedded:
function createFlashMovie(blobUrl){
var obj = document.createElement("object");
obj.setAttribute("width", "800");
obj.setAttribute("height", "600");
obj.setAttribute("type", "application/x-shockwave-flash");
obj.setAttribute("data", blobUrl); //use the object url here
document.body.appendChild(obj);
}
...and there you have it, no additional http request for the swf file.
This is probably a dumb question, but I am new to Web programming. I am trying to communicate with the Google Drive using client side JavaScript and CORS. I first used the jsclient library and that worked fine:
request = gapi.client.drive.files.list( {'q': " trashed = false " } );
Using CORS, my code looks like:
var xhr = new XMLHttpRequest();
xhr.open('GET','https://www.googleapis.com/drive/v2/files');
var mysearch = encodeURIComponent("q=trashed=false");
xhr.open('GET',"https://www.googleapis.com/drive/v2/files?" +mysearch,true);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() { handleResponse(xhr.responseText); };
xhr.onerror = function() { handleResponse(null); };
xhr.send();
I have tried:
var mysearch = encodeURIComponent("q=trashed=false");
var mysearch = encodeURIComponent("trashed=false");
var mysearch = encodeURIComponent("q='trashed=false'");
They all return the list of all the files. If I don't have a search string, I also get all the files.
I would like to have other search parameters also, using &, but I can't get just one to work.
How do I format the mysearch string?
Encode only the value part of the parameter:
var url = 'https://www.googleapis.com/drive/v2/files?q=' + encodeURIComponent("'trashed=false'")