This article is one in a series of articles about WebGL. ... 'WebGLRenderingContext': The image element contains cross-origin data, and may not be loaded.
English
Français
日本語
한국어
Polski
Portuguese
Русский
简体中文
TableofContents
WebGLFundamentals.org
Fix,Fork,Contribute
WebGL-CrossOriginImages
ThisarticleisoneinaseriesofarticlesaboutWebGL.Ifyouhaven'tread
themIsuggestyoustartwithanearlierlesson.
InWebGLit'scommontodownloadimagesandthenuploadthemtotheGPUtobe
usedastextures.There'sbeenseveralsamplesherethatdothis.For
examplethearticleaboutimageprocessing,the
articleabouttexturesandthearticleabout
implementing2ddrawImage.
Typicallywedownloadanimagesomethinglikethis
//createsatextureinfo{width:w,height:h,texture:tex}
//Thetexturewillstartwith1x1pixelsandbeupdated
//whentheimagehasloaded
functionloadImageAndCreateTextureInfo(url){
vartex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
//Fillthetexturewitha1x1bluepixel.
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,1,1,0,gl.RGBA,gl.UNSIGNED_BYTE,
newUint8Array([0,0,255,255]));
//let'sassumeallimagesarenotapowerof2
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
vartextureInfo={
width:1,//wedon'tknowthesizeuntilitloads
height:1,
texture:tex,
};
varimg=newImage();
img.addEventListener('load',function(){
textureInfo.width=img.width;
textureInfo.height=img.height;
gl.bindTexture(gl.TEXTURE_2D,textureInfo.texture);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,img);
});
img.src=url;
returntextureInfo;
}
Theproblemisimagesmighthaveprivatedatainthem(forexampleacaptcha,asignature,anakedpicture,...).
Awebpageoftenhasadsandotherthingsnotindirectcontrolofthepageandsothebrowserneedstoprevent
thosethingsfromlookingatthecontentsoftheseprivateimages.
Justusingisnotaproblembecausealthoughtheimagewillgetdisplayedby
thebrowserascriptcannotseethedatainsidetheimage.TheCanvas2DAPI
hasawaytoseeinsidetheimage.Firstyoudrawtheimageintothecanvas
ctx.drawImage(someImg,0,0);
Thenyougetthedata
vardata=ctx.getImageData(0,0,width,heigh);
But,iftheimageyoudrewcamefromadifferentdomainthebrowserwillmarkthecanvasastaintedand
you'llgetasecurityerrorwhenyoucallctx.getImageData
WebGLhastotakeitevenonestepfurther.InWebGLgl.readPixelsistheequivalentcalltoctx.getImageData
soyou'dthinkmaybejustblockingthatwouldbeenoughbutitturnsoutevenifyoucan'treadthepixels
directlyyoucanmakeshadersthattakelongertorunbasedonthecolorsintheimage.Usingthatinformation
youcanusetimingtoeffectivelylookinsidetheimageindirectlyandfindoutitscontents.
So,WebGLjustbansallimagesthatarenotfromthesamedomain.Forexamplehere'sashortsample
thatdrawsarotatingrectanglewithatexturefromanotherdomain.
Noticethetextureneverloadsandwegetanerror
clickheretoopeninaseparatewindow
Howdoweworkaroundthis?
EnterCORS
CORS=CrossOriginResourceSharing.It'sawayforthewebpagetoasktheimageserverforpermission
tousetheimage.
TodothiswesetthecrossOriginattributetosomethingandthenwhenthebrowsertriestogetthe
imagefromtheserver,ifit'snotthesamedomain,thebrowserwillaskforCORSpermission.
...
+img.crossOrigin="";//askforCORSpermission
img.src=url;
Thereare3valuesyoucansetcrossOriginto.Oneisundefinedwhichisthedefaultwhichmeans
"donotaskforpermission".Anotheris"anonymous"whichmeansaskforpermissionbutdon'tsendextrainfo.
Thelastis"use-credentials"whichmeanssendcookiesandotherinfotheservermightlookattodecide
whetherornotitgivepermission.IfcrossOriginissettoanyothervalueit'sthesameassetting
ittoanonymous.
Wecanmakeafunctionthatchecksiftheimagewe'retryingtoloadisonthesameoriginandif
sosetsthecrossOriginattribute.
functionrequestCORSIfNotSameOrigin(img,url){
if((newURL(url,window.location.href)).origin!==window.location.origin){
img.crossOrigin="";
}
}
Andwecanuseitlikethis
...
+requestCORSIfNotSameOrigin(img,url);
img.src=url;
clickheretoopeninaseparatewindow
It'simportanttonoteaskingforpermissiondoesNOTmeanyou'llbegrantedpermission.
Thatisuptotheserver.Githubpagesgivepermission,flickr.comgivespermission,
imgur.comgivespermission,butmostwebsitesdonot.Togivepermissiontheserver
sendscertainheaderswhensendingtheimage.
It'salsoimportanttonotethattheservergivingpermissionisnotenough.Ifthe
imageisfromanotherdomainyoumustsetthecrossOriginattributeorelseyou
willnotbeabletousetheimageeveniftheserversendsthecorrectheaders.
MakingApachegrantCORSpermission
Ifyou'rerunningawebsitewithapacheandyouhavethemod_rewriteplugininstalled
youcangrantblanketCORSsupportbyputting
HeadersetAccess-Control-Allow-Origin"*"
Intheappropriate.htaccessfile.
English
Français
日本語
한국어
Polski
Portuguese
Русский
简体中文
Fundamentals
Fundamentals
HowItWorks
ShadersandGLSL
WebGLStateDiagram
ImageProcessing
ImageProcessing
ImageProcessingContinued
2Dtranslation,rotation,scale,matrixmath
2DTranslation
2DRotation
2DScale
2DMatrices
3D
Orthographic3D
3DPerspective
3DCameras
Lighting
DirectionalLighting
PointLighting
SpotLighting
StructureandOrganization
LessCode,MoreFun
DrawingMultipleThings
SceneGraphs
Geometry
Geometry-Lathe
Loading.objfiles
Loading.objw.mtlfiles
Textures
Textures
DataTextures
Using2orMoreTextures
CrossOriginImages
PerspectiveCorrectTextureMapping
PlanarandPerspectiveProjectionMapping
RenderingToATexture
RendertoTexture
Shadows
Shadows
Techniques
2D
2D-DrawImage
2D-MatrixStack
Sprites
3D
Cubemaps
Environmentmaps
Skyboxes
Skinning
Fog
Picking(clickingonstuff)
Text
Text-HTML
Text-Canvas2D
Text-UsingaTexture
Text-UsingaGlyphTexture
Textures
RampTextures(ToonShading)
GPGPU
GPGPU
Tips
SmallestPrograms
DrawingWithoutData
Shadertoy
PullingVertices
Optimization
IndexedVertices(gl.drawElements)
InstancedDrawing
Misc
SetupAndInstallation
Boilerplate
ResizingtheCanvas
Animation
Points,Lines,andTriangles
MultipleViews,MultipleCanvases
VisualizingtheCamera
WebGLandAlpha
2Dvs3Dlibraries
Anti-Patterns
WebGLMatricesvsMathMatrices
PrecisionIssues
Takingascreenshot
PreventtheCanvasBeingCleared
GetKeyboardInputFromaCanvas
UseWebGLasBackgroundinHTML
CrossPlatformIssues
QuestionsandAnswers
Reference
Attributes
TextureUnits
Framebuffers
readPixels
References
HelperAPIDocs
TWGL,AtinyWebGLhelperlibrary
github
Questions?Askonstackoverflow.
Issue/Bug?Createanissueongithub.
Usecodegoeshere
forcodeblocks
commentspoweredbyDisqus