Wie kann ich laden Sie ein stylesheet, das durch ajax UND eine callback-wenn der laden fertig ist
Ich brauche, zu laden, eine Reihe von CSS-Dateien durch ajax und eine animation, wenn Sie das stylesheet geladen wurde, andernfalls wird die animation scheitern.
Was habe ich so gemacht und funktioniert ziemlich gut, bis ich kam accross tun, diese cross-domain ist:
$.get(resource.url, {cache:true}, function(css) {
//Now that the stylesheet is in the browser cache, it will load instantly:
$("head").append($("<link>",{
rel: "stylesheet",
type: "text/css",
href: resource.url
}));
}).then(function(){
//Animation here that depends on the loaded css
});
Dies funktioniert gut, solange resource.url
ist auf der gleichen domain. Sobald ich versuche, das laden der css von einer anderen Domäne $.get
wird scheitern wie diese:
XMLHttpRequest cannot load https://example.com/style.css. Origin https://example.com is not allowed by Access-Control-Allow-Origin.
Also habe ich versucht, hinzufügen von CORS in der Kopfzeile durch .htaccess
:
<IfModule mod_headers.c>
#cross domain access is okay for resources (#107)
<FilesMatch "\.(css|js)$">
Header add Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
Dadurch wird die CORS-header, um alle CSS-und JS-Ressourcen.
Aus irgendeinem Grund CORS scheint nicht zu haben eine Wirkung auf, entweder chrome oder firefox (neueste Versionen).
Kam ich auch zu bemerken, dass dieselbe Domäne-Richtlinie wird nicht erzwungen, wenn dabei $.getScript
für js-Dateien, aber es ist für $.get
:
$.get("https://example.com/script.js", {cache: false}, $.noop, "script");
//works regardless of CORS
aber:
$.get("https://example.com/script.js", {cache: false}, $.noop);
//does not work (cross domain policy violation)
So, da CORS ist nicht allgemein unterstützt und nicht einmal scheinen, das problem zu lösen für Sie einen modernen browser, ich brauche etwas, das verhält sich wie $.getScript
, aber für CSS-stylesheets.
Muss es asynchrone und eine callback-Mechanismus.
Irgendwelche Ideen? Vielen Dank im Voraus...
- Zur Klärung: deine Seite auf
foo.com
ist das ausführen einer fetch-Anweisung eine CSS-Ressource auf einer anderen domainbar.com
. Sie haben Hinzugefügt die CORS-Header der Seiten, die aufbar.com
, richtig? - ich habe den Header für die css-Ressourcen. Sollte es auf der html-Seiten?
- Nein, ich wollte nur sicherstellen, dass Sie nicht versehentlich die Einstellung der CORS-Header auf der Seite/domain, mit dem Abruf. Sie müssen CORS-Header für die cross-domain-Ressourcen, die heruntergeladen wird, was bedeutet, dass Sie Steuern müssen, dass cross-domain-Ressourcen. CORS ist eine Art zu sagen, "hey, jeder, es ist okay, auf diese Ressource zuzugreifen, die im cross-domain-Weise," nicht eine Art zu sagen: "okay, die Seite auf meiner domain ist, gehen Sie weiter, einen Zugang, was auch immer-domains, die Sie wollen". Sie machen nicht klar, was Sie versuchen zu tun, so wollte ich das klären.
- gut, dass ist es, was ich dachte und wie ich es umgesetzt. Letzteres würde keinen Sinn machen überhaupt...
- Okay, Super. Schreiben Sie eine Antwort jetzt!
- Toll, wir freuen uns auf Sie. Danke.
- Soweit die CORS betroffen ist-nicht mein cup of joe. Allerdings würde ich gerne teilen (was ich denke) ist etwas wertvolles wissen. jQuery
append()
ist eine synchrone Funktion. Was bedeutet, dass nichts ausgeführt wird, bis das anfügen abgeschlossen ist. Dies bedeutet, dass Sie brauchen keinethen
Anweisung, einfach dieanimate()
nach der$('head').append()
Funktion. - ja du hast Recht, aber die Art und Weise ist es wirklich implementiert ist (ich habe gerade eded die entsprechenden Schnipsel hier) ist wie dieser:
return $.get(...,function(){...});
und die dann so: `$.getStyleSheet(...).dann();, aber thx. Auch dies ist nicht so viel über CORS. CORS ist nur ein Grund, warum ich die aktuelle Methode nicht funktioniert, aber die Lösung sollte es nicht sein, in Bezug auf cors als alte Browser (IE ofc) nicht unterstützen. - Sie, sir, sind Sie ein Gentleman und ein Gelehrter. Ich Wünsche Ihnen das allerbeste!
- Ich denke JsFiddle.net hat bereits eine Lösung für das einbinden von stylesheets und/oder andere Ressourcen wie JS. Sie können die Ansicht-Quelltext Ihrer Website.
Du musst angemeldet sein, um einen Kommentar abzugeben.
$.get
nutzt Ajax, die müssen gehorchen den Gleichen Ursprung Richtlinie.$.getScript
normalerweise verwendet Ajax, aber es hat auch eine fallback-option für cross-domain Verwendung. Skripte importiert über<script>
tag unterliegen nicht Gleichen Ursprungs Regeln, so jQuery fügt nur ein<script>
tag auf die Seite und setzt seinensrc
Attribut für die angeforderte Skript-URL.Dieselbe Befreiung ist für die CSS-Ressourcen geladen durch
<link>
- tags. In einer perfekten Welt, sollten Sie in der Lage sein 1.) erstellen Sie eine neue<link>
element, 2) seinehref
- Attribut auf die richtige URL und 3) zu hörenload
- event auf das element. Ich habe ein callback zu diese Lösung aus dem jQuery-Foren:Ein kleines problem hier: es funktioniert nicht cross-browser.
<link>
tags nicht Feuerload
Veranstaltungen in allen Browsern -- siehe die jQuery-bug-report für die$.getCSS
Funktion, die gewesen sein könnte.So, der general-Fall Abhilfe ist ein wenig verrückt,: fügen Sie die CSS-URL als Quelle einer neuen
<img>
tag und hören für seineonerror
handler:Könnten Sie auch hinzufügen, ein bisschen Optimierung und hören
load
Veranstaltung auf der<link>
(für Browser, die es unterstützen) und eineerror
Veranstaltung auf der<img>
(für diejenigen, die nicht), und etwas Logik, um sicherzustellen, das callback wird immer nur einmal aufgerufen, falls beide Ereignisse eintreten.Da für die Herstellung
$.getCSS
Gegenzug ein deferred-Objekt, das ist ein bisschen außerhalb mein Fachgebiet, aber es gibt keinen theoretischen Grund, warum es konnte nicht getan werden.load
Veranstaltungen auf unserer<link>
Elemente, leider. Jedoch, wenn Ihr browser/server ist die intelligente Zwischenspeicherung, sollte es nur download der Inhalt der CSS-Datei einmal; die zweite Anforderung zurückgeben soll, ein 304 not Modified message.animationstart
Ereignis auf, das versteckte element, und Sie wissen, dass die CSS-Datei geladen wurde. Wieder erfordert diese Lösung geplant, die Zusammenarbeit zwischen den stylesheet und die Seite selbst, es ist keine gute Allgemeine Lösung für pull-in jeder CSS in jede Seite.Zusammen meine eigene Implementierung von apsillers' Antwort mit einem latenten, anstatt ein jQuery-plugin.
Diesem Thema ist mehrere Jahre alt, und ich weiß nicht, wenn das backup-Ereignis auf die img ist immer noch notwendig, aber es schien ziemlich trivial zu implementieren.
Für meinen speziellen use-case,, weiß ich nicht wirklich Pflege, wenn das Blatt konnte nicht geladen werden, so dass beide Fälle gelöst sind. Wenn Sie wollten, Griff die Fälle getrennt, die Sie nicht passieren konnten, ein argument für die
finish
handler zu beheben/ablehnen angemessen.