2012-04-10 15 views
6

Attualmente devo gestire il sistema legacy scritto in VB. Non sto bene con VB e ASP, quindi ho deciso che il nuovo codice per questo sistema verrà scritto in JScript.Chiamare una funzione scritta su VB da un codice JScript (ASP classico)

Tuttavia, c'è qualche problema con l'interoperabilità tra le due lingue: vale a dire, quando sto cercando di chiamare una qualche funzione dichiarata in <script language="vbscript"> tag, fallisce con un "Previsto oggetto" errore (se la lingua della pagina è VBScript) e viceversa.

Vale a dire, il seguente codice:

inc.asp

<script language="vbscript" runat="server"> 
Sub VBTestFunction(Message) 
    Response.Write "VBTestFunction: " & Message 
End Sub 
</script> 
<script language="javascript" runat="server"> 
function JSTestFunction(Message) { 
    Response.Write("JSTestFunction: " + Message); 
} 
</script> 

testjs.asp

<%@ Language="JavaScript" %> 
<!-- #include file="inc.asp"--> 
<script language="javascript" runat="server"> 
    VBTestFunction("from javascript"); 
    JSTestFunction("from javascript"); 
</script> 
<script language="vbscript" runat="server"> 
    Call VBTestFunction("from vbscript") 
    Call JSTestFunction("from vbscript") 
</script> 

non riesce con il seguente errore:

VBTestFunction: from vbscript 
Microsoft VBScript runtime error '800a000d' 
Type mismatch: 'JSTestFunction' 
/test.asp, line 9 

(se commenterò la riga specifica, le altre tre dichiarazioni funzioneranno correttamente); impostare la lingua della pagina per VBScript

<%@ Language="VBScript" %> 
<!-- #include file="inc.asp"--> 
<script language="javascript" runat="server"> 
    VBTestFunction("from javascript"); 
    JSTestFunction("from javascript"); 
</script> 
<script language="vbscript" runat="server"> 
    Call VBTestFunction("from vbscript") 
    Call JSTestFunction("from vbscript") 
</script> 

non riesce con il seguente errore:

Microsoft JScript runtime error '800a138f' 
Object expected 
/test.asp, line 4 

(ancora una volta, se sarò commentare la riga specifica, altre tre affermazioni funzionano bene).

C'è un MSDN article sulla combinazione di VB e JS nella stessa applicazione, ma dall'articolo sembra che il codice di esempio dovrebbe funzionare, come TestFunction è dichiarato in un altro file ed è una funzione dopo tutto.

C'è un modo per rendere tutto funzionante e chiamare entrambi VBTestFunction e JSTestFunction dal codice VB e JS? Immagino che ce ne dovrebbe essere uno, altrimenti non sarebbe il caso di mischiare JS e VB.

+2

Osserva attentamente l'articolo che hai menzionato, in particolare la parte in cui si dice "Server Script Order of Execution". Il tuo problema sta lì. –

+1

L'articolo disegna in particolare la linea tra il flusso del codice principale ("script del server in linea") e la dichiarazione delle subroutine. Dall'articolo sembra che una subroutine possa essere dichiarata in qualsiasi lingua e che io sia in grado di chiamarla da qualsiasi lingua. – penartur

risposta

6

Ho seguito questa domanda per un po 'e Salman ha praticamente risposto, ma ci sono alcune cose che potrebbero essere chiarite. Prima di tutto c'è un problema chiave con il riferimento all'articolo. Si dice che l'ordine di esecuzione è questo: -

1.Script in elements in nondefault languages
2.Inline script
3.Script in elements in the default language

Il suo male, o almeno la sua scaduto (lo fa dopo ogni riferimento IIS4). Lo "script inline" (ovvero lo script nella lingua predefinita) non viene trattato diversamente dagli elementi di script della stessa lingua.

Ecco come ragionare su ciò che sta accadendo.

  • Prima di qualsiasi analisi inizia tutti i punti di includere vengono risolti e sostituiti da contenuti dai file di inclusione per creare un unico "file" lessicale. Questo viene creato prima che avvenga qualsiasi parsing.

  • Il codice di script viene raccolto da questo "file" per ogni lingua. È possibile immaginare più file (uno per lingua) aggiunti a ogni chunk. Si noti che questo è il motivo per cui <% %> e <script runat="server" per la lingua predefinita sono praticamente indistinguibili.

  • Qualsiasi contenuto statico (ovvero contenuto esterno a un tag di script runat="server" o <% %>) è considerato parte del codice per la lingua predefinita. Un modulo speciale di Response.Write che invia i byte del contenuto statico alla radice della risposta viene creato e aggiunto al codice lingua predefinito nel punto in cui è stato trovato nel file originale.

  • Ora abbiamo uno o più script pronti per essere elaborati dai rispettivi motori di script. Gli script di lingua non predefiniti sono analizzati e eseguiti prima. Qualsiasi identificatore globale creato, che sia per una funzione o una variabile, viene aggiunto all'ambiente di script. Tuttavia, poiché lo script della lingua predefinita non è stato elaborato affatto, a questo punto non è ancora disponibile nulla che possa successivamente aggiungere all'ambiente di script globale.

  • Nel momento in cui lo script della lingua predefinita viene analizzato ed eseguito, tutti gli identificativi globali creati dagli script di lingua precedenti saranno stati aggiunti all'ambiente di script e sono quindi disponibili per l'utilizzo da codice in linea.

Si dovrebbe nota attentamente che una funzione lingua predefinita può essere chiamato dal codice in una funzionenella lingua non predefinita a condizione che mette in funzione non predefinita può essere fatta risalire all'esecuzione in linea della lingua predefinita.

Per esempio, se la lingua predefinita è JScript si può avere una funzione VBScript (FNA) chiamare una funzione dichiarata in JScript (FNB) fino a quando la chiamata a fnA è fatto come parte dell'esecuzione linea di JScript. IOW JScript può chiamare in VBScript che a sua volta può chiamare in VBScript e così via, il fattore limitante è il motore che la parte superiore di questa catena deve essere JScript in questo scenario.

Nel codice di esempio è presente il codice a livello globale (in linea) del VBScript che tenta di chiamare una funzione dichiarata nel linguaggio JScript predefinito. Se segui i punti precedenti, vedrai che nel momento in cui viene eseguito la funzione chiamata non esiste.

+0

Siamo spiacenti, ma l'ordine di esecuzione menzionato nell'articolo è ancora valido. Esegui [questo script] (http://snipt.org/uhEf7), [questo] (http://snipt.org/uhEe0), e [questo] (http://snipt.org/uhEd7) su IIS7 e annotare l'ordine di esecuzione: rimane lo stesso, esattamente come descritto nell'articolo. Alcune delle affermazioni nella tua risposta sono sbagliate, in particolare quelle relative all'ordine di esecuzione. –

+0

Come per la nota: intendi che la risoluzione dei nomi globali avviene in fase di runtime, in modo che, in pratica, tutte le chiamate di funzione siano in linea e quindi il codice risultante viene eseguito sotto la regola "il codice nella lingua non predefinita viene eseguito per primo, il codice nella lingua predefinita viene eseguito per ultimo "? – penartur

0

Non conosco tutte le regole, ma questo funziona per me:

Test.asp:

<%@ language="JavaScript" %> 

<script language="VBScript" runat="server" src="mix2.vbs"></script> 

<script language="JavaScript" runat="server"> 
    TestFunction("from javascript"); 
</script> 

mix2.vbs:

Sub TestFunction (message) 
    Response.Write message 
End Sub 

Avviso:

  • non c'è il tag <script> nel file vbs che diventa incl uded.
  • il tag <%@ language="..." %> in alto, dovrebbe indicare la lingua "primaria". I blocchi <script> che utilizzano la lingua secondaria (nel tuo caso, VBScript) saranno quindi interpretati e disponibili per qualsiasi codice nella lingua principale.

forse relativa: How can I use Javascript OO classes from VBScript, in an ASP-Classic or WSH environment?

+0

Ho modificato la mia risposta. Il tuo suggerimento risolve il problema originale specifico, ma interrompe la capacità di chiamare le funzioni JS dal codice VB. – penartur

+0

Non è così. Hai solo bisogno di ridigitare la dichiarazione della lingua. – Cheeso

2

vi incoraggio a non mescolare linguaggi di scripting. In the article you mentioned, v'è una rubrica dal titolo "Server Order Script di esecuzione", in cui si dice:

... However, you are then at the mercy of the order of execution of the IIS ASP processor. For example, if you create server script and run it in IIS 4.0, you'll find this execution order:

  1. Script in <SCRIPT> elements in nondefault languages
  2. Inline script
  3. Script in <SCRIPT> elements in the default language

Tenendo questo in mente, ecco come viene eseguito lo script testjs.asp, i commenti indicano ordine di esecuzione:

<%@ Language="JavaScript" %> 
<script language="vbscript" runat="server"> 
    '' #1 
    Sub VBTestFunction(Message) 
     Response.Write "VBTestFunction: " & Message 
    End Sub 
</script> 
<script language="javascript" runat="server"> 
    // #3 
    function JSTestFunction(Message) { 
     Response.Write("JSTestFunction: " + Message); 
    } 
</script> 
<script language="javascript" runat="server"> 
    // #4 
    VBTestFunction("from javascript"); 
    JSTestFunction("from javascript"); 
</script> 
<script language="vbscript" runat="server"> 
    '' #2 
    Call VBTestFunction("from vbscript") 
    Call JSTestFunction("from vbscript") 
</script> 

avviso la linea che causa l'errore:

Call JSTestFunction("from vbscript") 

il suo ordine di esecuzione è # 2; a questo punto la funzione JSTestFunction non è definita (è definita successivamente nell'ordine di esecuzione).

Ora per il file testvbs.asp:

<%@ Language="VBScript" %> 
<script language="vbscript" runat="server"> 
    '' 3 
    Sub VBTestFunction(Message) 
     Response.Write "VBTestFunction: " & Message 
    End Sub 
</script> 
<script language="javascript" runat="server"> 
    // 1 
    function JSTestFunction(Message) { 
     Response.Write("JSTestFunction: " + Message); 
    } 
</script> 
<script language="javascript" runat="server"> 
    // 2 
    VBTestFunction("from javascript"); 
    JSTestFunction("from javascript"); 
</script> 
<script language="vbscript" runat="server"> 
    '' 4 
    Call VBTestFunction("from vbscript") 
    Call JSTestFunction("from vbscript") 
</script> 

La linea che causa l'errore:

VBTestFunction("from javascript"); 

Anche in questo caso, VBTestFunction è chiamato prima che venga definita. La soluzione è cercare di non mescolare i linguaggi di scripting. Se è assolutamente necessario, rivedere l'ordine dei tuoi script.

Edit - Esempio

Se è stata impostata @ Language="JavaScript" allora questo codice dovrebbe funzionare come previsto:

<!-- inc.asp--> 
<script language="vbscript" runat="server"> 
    Sub VBTestFunction(Message) 
     Response.Write "VBTestFunction: " & Message 
    End Sub 
</script> 
<% 
    function JSTestFunction(Message) { 
     Response.Write("JSTestFunction: " + Message); 
    } 
%> 

<!-- testjs.asp --> 
<%@ Language="JavaScript" %> 
<!-- #include file="inc.asp"--> 
<% 
    // at this point, both functions are available 
    VBTestFunction("from inline JavaScript"); 
    JSTestFunction("from inline JavaScript"); 
%> 

Se si desidera utilizzare @ Language="VBScript" allora si deve ri-organizzare tutto il codice:

<!-- inc.asp--> 
<script language="javascript" runat="server"> 
    function JSTestFunction(Message) { 
     Response.Write("JSTestFunction: " + Message); 
    } 
</script> 
<% 
    Sub VBTestFunction(Message) 
     Response.Write "VBTestFunction: " & Message 
    End Sub 
%> 

<!-- testvbs.asp --> 
<%@ Language="VBScript" %> 
<!-- #include file="inc.asp"--> 
<% 
    ' at this point, both functions are available 
    VBTestFunction("from inline VBScript") 
    JSTestFunction("from inline VBScript") 
%> 
+0

L'articolo che ho citato dice specificamente che è importante solo per il codice che fa qualcosa, non per le dichiarazioni di procedure. Stai cercando di dire che è semplicemente impossibile chiamare una funzione scritta in una lingua primaria da qualsiasi codice scritto in una lingua non primaria? – penartur

+0

L'articolo che lei ha citato vi dà alcuni suggerimenti (e trucchi) su come fare per mescolare linguaggi di scripting come _... usare sia