arcgis-js-api

PictureMarkerSymbol accessing unallowed blob even when using base 64 image from url property Arcgis JS Api 4.27 - Possible Bug


The PictureMarkerSymbol is accessing unallowed blob even when using base 64 image from url property in Arcgis JavaScript Api 4.27. When you setup a PictureMarkerSymbol specify the url of the image:

const mySymbol = {
            type: "picture-marker",
            url: "/Content/myimage.png",
            width: "48px",
            height: "48px",
            contentType: "image/png"
        };

When code is run and at the point where the picture marker symbol sets up to use the png (or the base64 image), arcgis javascript api 4.27 converts it to a blob. If you have your web server set to not allow access to blobs in the content security policy, you will get this error:

Error:

Refused to load the image 'blob:https://www.myserver.com/953e5424-d924-2c3a-92b4-4cf83c376042' because it violates the following Content Security Policy directive: "img-src * data:". Note that '*' matches only URLs with network schemes ('http', 'https', 'ws', 'wss'), or URLs whose scheme matches self's scheme. The scheme 'blob:' must be added explicitly.

I now attempt to use a base64 image and not refer to a png at all. However, picture marker symbol still tries to create a blob and breaks since it does not have access to do so on the client:

const mySymbol = {
            type: "picture-marker",
            url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=",
            width: "48px",
            height: "48px",
            contentType: "image/png"
        };

Same Error:

Refused to load the image 'blob:https://www.myserver.com/953e5424-d924-2c3a-92b4-4cf83c376042' because it violates the following Content Security Policy directive: "img-src * data:". Note that '*' matches only URLs with network schemes ('http', 'https', 'ws', 'wss'), or URLs whose scheme matches self's scheme. The scheme 'blob:' must be added explicitly.

I have no control over the server to allow blobs on the content security policy. How can this be resolved? This looks like an issue with the ArcGIS API 4.27 forcing the use of "blob" to setup the picture marker symbols.


Solution

  • The following is the work-around. The issue above still remains an issue with ESRI/ArcGIS forcing the use of blobs in their libraries. The work around involves using either a SimpleMarkerSymbol or a WebStyleSymbol instead of using the PictureMarkerSymbol. You can create an SVG picture and then use the SimpleMarkerSymbol. Set the SVG picture in the path property as seen below. Set the yoffset to half the size of the image to display the image in the correct location on the map. Below example sets image to 30px and the yoffset to 15px to display point in correct location. For example:

    const mySimpleMarkerSymbol= {
            type: "simple-marker",
            path: "M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z",
            color: "red",
            outline: {
                color: "white"
            },
            xoffset: "0",
            yoffset: "15px",
            size: "30px",
            angle: "0",
            style: "path"
        };
    

    The path property.

    The path property above defines the image. Use an SVG editor such as this one to edit/create the image.

    Option number two involves using a WebStyleSymbol with premade graphics that can be selected in this link. Here is an example:

    const myWebStyleSymbol = {
            type: "web-style",
            name: "tear-pin-2",
            styleName: "Esri2DPointSymbolsStyle"
    };