Вы можете взглянуть на образец Facebook Auth , чтобы увидеть реализацию потока Auth, о котором говорит Том. Для Azure AD это почти то же самое. Я опубликовал некоторые детали реализации на , как получить Azure Active Directory B2C, работающий с Bot Framework?
Обновить
Есть два новые образцы, которые вы можете захотеть взглянуть, поскольку они реализуют обсуждаемый рабочий процесс.
Можно записать динамические теги script (использующий Прототип ):
new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});
проблема здесь состоит в том, что мы не знаем , когда внешний файл сценария полностью загружается.
Мы часто хотим наш подчиненный код очень следующей строки и любим писать что-то как:
if (iNeedSomeMore) {
Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
myFancyMethod(); // cool, no need for callbacks!
}
существует умный способ ввести зависимости от сценария без потребности обратных вызовов. Просто необходимо вытянуть сценарий через синхронный запрос Ajax и оценка сценарий на глобальном уровне.
при использовании Прототипа метод Script.load похож на это:
var Script = {
_loadedScripts: [],
include: function(script) {
// include script only once
if (this._loadedScripts.include(script)) {
return false;
}
// request file synchronous
var code = new Ajax.Request(script, {
asynchronous: false,
method: "GET",
evalJS: false,
evalJSON: false
}).transport.responseText;
// eval code on global level
if (Prototype.Browser.IE) {
window.execScript(code);
} else if (Prototype.Browser.WebKit) {
$("head").first().insert(Object.extend(
new Element("script", {
type: "text/javascript"
}), {
text: code
}
));
} else {
window.eval(code);
}
// remember included script
this._loadedScripts.push(script);
}
};
все крупнейшие библиотеки JavaScript как jscript, прототип, YUI имеют поддержку загрузки файлов сценария. Например, в YUI, после загрузки ядра можно сделать следующее для загрузки календарного управления
var loader = new YAHOO.util.YUILoader({
require: ['calendar'], // what components?
base: '../../build/',//where do they live?
//filter: "DEBUG", //use debug versions (or apply some
//some other filter?
//loadOptional: true, //load all optional dependencies?
//onSuccess is the function that YUI Loader
//should call when all components are successfully loaded.
onSuccess: function() {
//Once the YUI Calendar Control and dependencies are on
//the page, we'll verify that our target container is
//available in the DOM and then instantiate a default
//calendar into it:
YAHOO.util.Event.onAvailable("calendar_container", function() {
var myCal = new YAHOO.widget.Calendar("mycal_id", "calendar_container");
myCal.render();
})
},
// should a failure occur, the onFailure function will be executed
onFailure: function(o) {
alert("error: " + YAHOO.lang.dump(o));
}
});
// Calculate the dependency and insert the required scripts and css resources
// into the document
loader.insert();
я использовал еще одно решение, которое я нашел в сети..., этот находится под creativecommons и этим проверки, если источник был включен до вызова функции ...
можно найти файл здесь: include.js
/** include - including .js files from JS - bfults@gmail.com - 2005-02-09
** Code licensed under Creative Commons Attribution-ShareAlike License
** http://creativecommons.org/licenses/by-sa/2.0/
**/
var hIncludes = null;
function include(sURI)
{
if (document.getElementsByTagName)
{
if (!hIncludes)
{
hIncludes = {};
var cScripts = document.getElementsByTagName("script");
for (var i=0,len=cScripts.length; i < len; i++)
if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
}
if (!hIncludes[sURI])
{
var oNew = document.createElement("script");
oNew.type = "text/javascript";
oNew.src = sURI;
hIncludes[sURI]=true;
document.getElementsByTagName("head")[0].appendChild(oNew);
}
}
}
у кого-либо есть лучший путь?
я думаю, просто добавив, что сценарий к телу был бы легче тогда добавление его к последнему узлу на странице. Как насчет этого:
function include(url) {
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
document.body.appendChild(s);
}
Вот некоторый пример кода, который я нашел..., что у кого-либо есть лучший путь?
function include(url)
{
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
var nodes = document.getElementsByTagName("*");
var node = nodes[nodes.length -1].parentNode;
node.appendChild(s);
}
Я сделал в основном то же самое, что Вы сделали Adam, но с небольшой модификацией для проверки я добавлял к главному тегу, чтобы сделать задание. Я просто создал включать функцию (код ниже) для обработки и сценария и css файлов.
Эта функция также проверяет, чтобы удостовериться, что файл сценария или CSS не был уже загружен динамично. Это не проверяет на кодированные значения руки и, возможно, был лучший способ сделать это, но это служило цели.
function include( url, type ){
// First make sure it hasn't been loaded by something else.
if( Array.contains( includedFile, url ) )
return;
// Determine the MIME-type
var jsExpr = new RegExp( "js$", "i" );
var cssExpr = new RegExp( "css$", "i" );
if( type == null )
if( jsExpr.test( url ) )
type = 'text/javascript';
else if( cssExpr.test( url ) )
type = 'text/css';
// Create the appropriate element.
var tag = null;
switch( type ){
case 'text/javascript' :
tag = document.createElement( 'script' );
tag.type = type;
tag.src = url;
break;
case 'text/css' :
tag = document.createElement( 'link' );
tag.rel = 'stylesheet';
tag.type = type;
tag.href = url;
break;
}
// Insert it to the <head> and the array to ensure it is not
// loaded again.
document.getElementsByTagName("head")[0].appendChild( tag );
Array.add( includedFile, url );
}
Я использовал намного менее сложная версия недавно с jQuery:
<script src="scripts/jquery.js"></script>
<script>
var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
var $head = $("head");
for (var i = 0; i < js.length; i++) {
$head.append("<script src=\"" + js[i] + "\"></scr" + "ipt>");
}
</script>
Это работало отлично в каждом браузере, в котором я протестировал его: IE6/7, Firefox, Safari, Opera.
Обновление: версия jQuery меньше:
<script>
var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
for (var i = 0, l = js.length; i < l; i++) {
document.getElementsByTagName("head")[0].innerHTML += ("<script src=\"" + js[i] + "\"></scr" + "ipt>");
}
</script>
Техника, которую мы используем на работе, должна запросить файл JavaScript с помощью запроса Ajax и затем оценки () возврат. Если Вы пользуетесь библиотекой прототипа, они поддерживают эту функциональность в своем Ajax. Вызов запроса.
Просто узнанный о замечательной особенности в YUI 3 (во время записи доступного в предварительном выпуске). Можно легко вставить зависимости в библиотеки YUI и во "внешние" модули (что Вы ищете) без слишком большого количества кода: Загрузчик YUI.
Это также отвечает на Ваш второй вопрос относительно функции, вызванной, как только внешний модуль загружается.
Пример:
YUI({
modules: {
'simple': {
fullpath: "http://example.com/public/js/simple.js"
},
'complicated': {
fullpath: "http://example.com/public/js/complicated.js"
requires: ['simple'] // <-- dependency to 'simple' module
}
},
timeout: 10000
}).use('complicated', function(Y, result) {
// called as soon as 'complicated' is loaded
if (!result.success) {
// loading failed, or timeout
handleError(result.msg);
} else {
// call a function that needs 'complicated'
doSomethingComplicated(...);
}
});
Работавший отлично для меня и имеет преимущество руководящих зависимостей. Обратитесь к документации YUI для примера с календарем YUI 2.
Я настроил часть вышеупомянутого сообщения с рабочим примером. Здесь мы можем дать CSS и js в том же массиве также.
$(document).ready(function(){
if (Array.prototype.contains === undefined) {
Array.prototype.contains = function (obj) {
var i = this.length;
while (i--) { if (this[i] === obj) return true; }
return false;
};
};
/* define object that will wrap our logic */
var jsScriptCssLoader = {
jsExpr : new RegExp( "js$", "i" ),
cssExpr : new RegExp( "css$", "i" ),
loadedFiles: [],
loadFile: function (cssJsFileArray) {
var self = this;
// remove duplicates with in array
cssJsFileArray.filter((item,index)=>cssJsFileArray.indexOf(item)==index)
var loadedFileArray = this.loadedFiles;
$.each(cssJsFileArray, function( index, url ) {
// if multiple arrays are loaded the check the uniqueness
if (loadedFileArray.contains(url)) return;
if( self.jsExpr.test( url ) ){
$.get(url, function(data) {
self.addScript(data);
});
}else if( self.cssExpr.test( url ) ){
$.get(url, function(data) {
self.addCss(data);
});
}
self.loadedFiles.push(url);
});
// don't load twice accross different arrays
},
addScript: function (code) {
var oNew = document.createElement("script");
oNew.type = "text/javascript";
oNew.textContent = code;
document.getElementsByTagName("head")[0].appendChild(oNew);
},
addCss: function (code) {
var oNew = document.createElement("style");
oNew.textContent = code;
document.getElementsByTagName("head")[0].appendChild(oNew);
}
};
//jsScriptCssLoader.loadFile(["css/1.css","css/2.css","css/3.css"]);
jsScriptCssLoader.loadFile(["js/common/1.js","js/2.js","js/common/file/fileReader.js"]);
});