Three.js-DOMException:“操作不安全。” -最有可能是跨域问题

问题描述 投票:0回答:1

几年前,我已经为全景图片实现了Three.js查看器,现在我将网站移到另一个位置,Three.js出现了问题,不再愿意加载。

控制台中的错误消息:DOMException:“操作不安全。”

这里是我正在使用的html部分:

<div class="article-pano-gallery" style="display:table">
<img onclick="init('https://images.laurentwillen.be/sites/21/2017/05/photo-panoramique-360-Catane.jpg')" class="article-gallery-image pano-image" data-srcset="https://images.laurentwillen.be/sites/21/2017/05/photo-panoramique-360-Catane.jpg" src="https://images.laurentwillen.be/sites/21/2017/05/photo-panoramique-360-Catane-150x150.jpg" width="150" height="150">
</div>

对于JS部分:

<script async src="https://ajax.googleapis.com/ajax/libs/threejs/r84/three.min.js"></script>    
<script>
var camera, scene, renderer;
var isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0;

function init(full_image) 
   {
       var container, mesh;
    container = document.getElementById( 'background-section' );
    document.getElementById( 'background-section') .style.display='block';
    document.getElementById( 'pano-loading-section') .style.display='block';
    document.getElementById( 'close') .style.display='block';
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
    camera.target = new THREE.Vector3( 0, 0, 0 );
    scene = new THREE.Scene();
    var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 );
    // invert the geometry on the x-axis so that all of the faces point inward
    geometry.scale( - 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( {
    map: new THREE.TextureLoader().load( full_image )
        } );

mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth*0.95, window.innerHeight*0.95 );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onPointerStart, false );
document.addEventListener( 'mousemove', onPointerMove, false );
document.addEventListener( 'mouseup', onPointerUp, false );
document.addEventListener( 'wheel', onDocumentMouseWheel, false );
document.addEventListener( 'touchstart', onPointerStart, false );
document.addEventListener( 'touchmove', onPointerMove, false );
document.addEventListener( 'touchend', onPointerUp, false );

document.addEventListener( 'dragover', function ( event ) 
{
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';
}, false );

document.addEventListener( 'dragenter', function () 
{
    document.body.style.opacity = 0.5;
}, false );

document.addEventListener( 'dragleave', function () 
{
    document.body.style.opacity = 1;
}, false );

document.addEventListener( 'drop', function ( event ) 
{
    event.preventDefault();
    var reader = new FileReader();
    reader.addEventListener( 'load', function ( event ) {
        material.map.image.src = event.target.result;
        material.map.needsUpdate = true;
    }, false );
    reader.readAsDataURL( event.dataTransfer.files[ 0 ] );
        document.body.style.opacity = 1;
    }, false );
            //
    window.addEventListener( 'resize', onWindowResize, false );
    document.getElementById( 'pano-loading-section') .style.display='none';
    animate();
}

function onWindowResize() 
{
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth*0.95, window.innerHeight*0.95 );
}

function onPointerStart( event ) 
{
    isUserInteracting = true;
    var clientX = event.clientX || event.touches[ 0 ].clientX;
    var clientY = event.clientY || event.touches[ 0 ].clientY;
    onMouseDownMouseX = clientX;
    onMouseDownMouseY = clientY;
    onMouseDownLon = lon;
    onMouseDownLat = lat;
}

function onPointerMove( event ) 
{
    if ( isUserInteracting === true ) 
        {
            var clientX = event.clientX || event.touches[ 0 ].clientX;
            var clientY = event.clientY || event.touches[ 0 ].clientY;
            lon = ( onMouseDownMouseX - clientX ) * 0.1 + onMouseDownLon;
            lat = ( clientY - onMouseDownMouseY ) * 0.1 + onMouseDownLat;
        }
}

function onPointerUp() 
{
    isUserInteracting = false;
}

function onDocumentMouseWheel( event ) 
{
    var fov = camera.fov + event.deltaY * 0.05;
    camera.fov = THREE.Math.clamp( fov, 10, 75 );
    camera.updateProjectionMatrix();
}

function animate() 
{
    requestAnimationFrame( animate );
    update();
}

function update() 
{
    if ( isUserInteracting === false ) 
        {
            lon += 0.1;
        }
    lat = Math.max( - 85, Math.min( 85, lat ) );
    phi = THREE.Math.degToRad( 90 - lat );
    theta = THREE.Math.degToRad( lon );
    camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
    camera.target.y = 500 * Math.cos( phi );
    camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );
    camera.lookAt( camera.target );
            /*
            // distortion
            camera.position.copy( camera.target ).negate();
            */
    renderer.render( scene, camera );
}


</script>   

我在另一个域上使用了相同的脚本来处理图像,并且运行良好,但是现在我已经移动了,它不再起作用了。

我想它与跨网域有关,但我不清楚确切的位置。我已经尝试了JS文件的本地版本,并且是同一问题。

JS中的错误发生在第121行。这是下面所要求的全文:

DOMException: "The operation is insecure." three.js:121:396
texImage2D https://wp.laurentwillen.be/js/three.js:121
n https://wp.laurentwillen.be/js/three.js:97
setTexture2D https://wp.laurentwillen.be/js/three.js:181
hf https://wp.laurentwillen.be/js/three.js:7
upload https://wp.laurentwillen.be/js/three.js:343
G https://wp.laurentwillen.be/js/three.js:147
renderBufferDirect https://wp.laurentwillen.be/js/three.js:165
n https://wp.laurentwillen.be/js/three.js:134
render https://wp.laurentwillen.be/js/three.js:180
update https://wp.laurentwillen.be/circuits/circuit-italie/catane/?bb:1679
animate https://wp.laurentwillen.be/circuits/circuit-italie/catane/?bb:1659

谢谢

three.js cross-domain
1个回答
0
投票

这绝对是CORS问题。我建议您熟悉how modern browsers handle cross-domain requests

我的最佳猜测是,您的images.laurentwillen.be服务器未配置为允许将资产传送到其他域。这是一项安全功能,因此其他人不会窃取您的带宽(您可能不希望通过使用服务器上托管的映像来释放数千个站点)。

对此问题有2种解决方案:

  1. 将图像托管在请求它​​们所在的域中。
  2. [了解如何让您的服务器允许将图像传送到使用它们的域。实现此目标的方法取决于您所运行的服务器的类型,并且您必须进行一些挖掘以弄清楚如何配置它,因此解决方案1将是最简单的。
© www.soinside.com 2019 - 2024. All rights reserved.