简体   繁体   中英

What's a clean way to have the server return a JavaScript function which would then be invoked?

My application is architected as a host of plug-ins that have not yet been written. There's a long reason for this, but with each new year, the business logic will be different and we don't know what it will be like (Think of TurboTax if that helps). The plug-ins consist of both server and client components. The server components deals with business logic and persisting the data into database tables which will be created at a later time as well. The JavaScript manipulates the DOM for the browsers to render afterward.

Each plugin lives in a separate assembly, so that they won't disturb the main application, ie, we don't want to recompile the main application. Long story short, I am looking for a way to return JavaScript functions to the client from an Ajax get request, and execute these JavaScript functions (which are just returned). Invoking a function in Javascript is easy. The hard part is how to organize or structure so that I won't have to deal with maintenance problem. So concat using StringBuilder to end up with JavaScript code as a result of calling toString() from the string builder object is out of the question.

I want to have no difference between writing JavaScript codes normally and writing Javascript codes for this dynamic purpose.

An alternative is to manipulate the DOM on the server side, but I doubt that it would be as elegantly as using jQuery on the client side. I am open for a C# library that supports chainable calls like jQuery that also manipulates the DOM too.

Do you have any idea or is it too much to ask or are you too confused?

Edit1 : The point is to avoid recompiling, hence the plug-ins architecture. In some other parts of the program, I already use the concept of dynamically loading Javascript files. That works fine. What I am looking here is somewhere in the middle of the program when an Ajax request is sent to the server.

Edit 2 : To illustrate my question:

Normally, you would see the following code. An Ajax request is sent to the server, a JSON result is returned to the client which then uses jQuery to manipulate the DOM (creating tag and adding to the container in this case).

var container = $('#some-existing-element-on-the-page');
$.ajax({
    type: 'get',
    url: someUrl,
    data: {'': ''},
    success: function(data) {                                                   
      var ul = $('<ul>').appendTo(container);

      var decoded = $.parseJSON(data);                
      $.each(decoded, function(i, e) {
         var li = $('<li>').text(e.FIELD1 + ',' + e.FIELD2 + ',' + e.FIELD3)
            .appendTo(ul);
      });                
    }        
});

The above is extremely simple. But next year, what the server returns is totally different and how the data to be rendered would also be different. In a way, this is what I want:

var container = $('#some-existing-element-on-the-page');
$.ajax({
    type: 'get',
    url: someUrl,
    data: {'': ''},
    success: function(data) {                           
      var decoded = $.parseJSON(data); 
      var fx = decoded.fx;
      var data = decode.data;
      //fx is the dynamic function that create the DOM from the data and append to the existing container
      fx(container, data);                  
    }        
});

I don't need to know, at this time what data would be like, but in the future I will, and I can then write fx accordingly.

I doubt you would need the ajax to return the javascript and you could probably just change the .js files each year.

Note that your scripts will need to be signed if they run cross domain

Anyway, you're probably looking for EVAL, which could in theory be used by hackers to mess with your site. It would also slow things down, and make things harder to debug...

Again, you probably shouldn't need to load javascript asynchronously. If the logic changes every year, that's just changing .js files. You would need to load it with ajax if the logic would change while the browser was still on the page... which could cause a problem in the programming namespaces anyway. (ie, you introduce new code in the live namespace of the old code, and the versions don't work nicely).

愚蠢的想法,但我可以建议您返回一个href到外部JS文件并加载而不是返回实际的JS代码?

It sounds like you have already decided on your architecture and you are determined to find a way to make it work. But rather than modify the DOM directly, why not just have the plug-ins return the relevant HTML and update the innerHTML of the container with their output?

Well, the cop-out is simply using eval. Sending the function as string from the server and eval('myhopefullyuncompromisedjavascriptcode');

success: function(data) {  
var decoded = $.parseJSON(data); 
  var fx = eval(decoded.fx); 
  //where the eval string would contain "(function(params){...})"
  var data = decode.data;
  //fx is the dynamic function that creates the DOM from the data and append to the existing container
  fx(container, data);      

The alternatives are not really that much greater though.

You could load on demand but, really, it amounts to the same thing except that it is encapsulated in a .js.
If someone has the ability to return random stringified js from your site, or, is able to make your ajax call point at somewhere else to load arbitrary js, then they are already able to load their own arbitrary js.

On the other hand, dynamic loading could save you some bw, in that you aren't sending the same stringified function over the wire and evaling it time and again, that same benefit could be derived from maintaining a clientside hash of functions though.

its a bit 'meh' from my pov.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM