2014-07-09 8 views
5

Dzisiaj spędzam trochę czasu próbując manipulować SVG za pomocą D3 (i jQuery). Mój cel: jest w stanie uzyskać dostęp/modyfikować lokalne SVG za pomocą JavaScript. Nie ma znaczenia, czy jest dostosowany do D3, ale to byłby dodatkowy punkt.Odbierz Uncaught SecurityError podczas uzyskiwania dostępu do obiektów SVG z Javascript

Wydaje się, że rozwiązanie, które działa dla innych ludzi nie pracuje dla mnie, który ma następujące javascript:

window.onload=function() { 
    // Get the Object by ID 
    var a = document.getElementById("svgObject"); 
    // Get the SVG document inside the Object tag 
    var svgDoc = a.contentDocument; 
    // Get one of the SVG items by ID; 
    var svgItem = svgDoc.getElementById("svgItem"); 
    // Set the colour to something else 
    svgItem.setAttribute("fill", "lime"); 
}; 

z tym HTML object

<object id="svgObject" data="img/svgfile.svg" type="image/svg+xml" height="50" width="50"></object> 

i oddzielnym pliku SVG

<svg height="40px" width="40px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800"> 
    <rect id="svgItem" width="800" height="800" fill="red"></rect> 
    <circle cx="400" cy="400" r="400" fill="blue"></circle> 
</svg> 

wszystko znalezione here. Jest to uproszczona wersja kodu znalezionego w this example. Mój kod JavaScript jest pokazany poniżej, prosto z mojego edytora:

window.onload = function() { 
    var checkObject = document.getElementById("checkers"); 
    var checkDoc = checkObject.contentDocument; 

    var cheese = checkDoc.getElementById('layer1'); 
    console.log(cheese); 
}; 

w przypadku gdy zmienia się nic, mój skrypt zostanie załadowany na dole ciała HTML jest. Poniżej znajduje się mój jedyny element HTML.

<object data="check.svg" type="image/svg+xml" width="100" id="checkers"></object> 

i mój plik SVG (tylko szary czek, nie krępuj się używać).

<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> 
    <g id="layer1" transform="translate(0,-952.36217)"> 
     <path id="rawCheck" fill="#dbdbdb" d="m18.75,1004.5,21.607,21.607,40.893-40.893-7.8571-7.8572-33.036,33.036-13.75-14.107z" stroke-opacity="0"/> 
    </g> 
</svg> 

Mój problem pochodzi z wywołaniem .contentDocument na checkObject, który powinny prostu być wzywającą .contentDocument na elemencie object ale otrzymuję ten bałagan:

Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLObjectElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.

wyjątkiem wszystko było zły kolor czerwony. To mnie zdezorientowało, ponieważ, o ile widzę, mój kod jest dość zbliżony do kopii działającego przykładu, ale oto jestem.

Próbowałem również z d3.xml() widziany w odpowiedzi this question „s i otrzymała następujący błąd

XMLHttpRequest cannot load file:///home/user/Documents/examples/d3/check.svg. Cross origin requests are only supported for HTTP.

jak również

Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'file:///home/user/Documents/examples/d3/check.svg'

Jeśli chcesz zobaczyć więcej szczegółów na mój d3.xml() próba Jestem szczęśliwy, aby zaktualizować to pytanie, po prostu myślałem, że istnieje już wiele bloków kodu.

+0

Będziesz musiał uruchomić to z lokalnego serwera. XMLHttpRequest nie jest dozwolony dla plików z lokalnym systemem plików. –

+0

Lub alternatywnie wypróbuj go na czymś innym niż Chrome. –

+0

Tak, Aleksander, masz rację, dziękuję bardzo. To rozwiązało oba problemy.Jeśli napiszesz jako odpowiedź, zaakceptuję to. – aidankmcl

Odpowiedz

3

W Chrome nie jest możliwe uzyskanie dostępu do zawartości zewnętrznego SVG przez JavaScript, gdy strona jest otwierana przez system plików (tzn. Adres URL ma protokół file://).

Aby obejść ten problem, można go otworzyć za pośrednictwem lokalnego serwera. Alternatywnie możesz disable the Same-Origin Policy web security feature do testowania przy użyciu argumentu linii poleceń z --disable-web-security. Firefox również nie ma tego ograniczenia, więc istnieje również ta opcja.