JavaScript

MVC

AngularJS

Testing

IDE

Compressors

Questions answered

How to enable CORS with secured services?

The following conditions should be met:
  • OPTIONS request should not be secured (Firefox fails)
  • The server should return the value different from * in Access-Control-Allow-Origin response header. The simplest is to return the value passed to the server in request header Origin.
  • Access-Control-Allow-Methods and Access-Control-Allow-Headers should contain the list of allowed methods and headers which are allowed be passed to the server.
# By default everything is static content:
SetEnvIf    Request_URI    ".*"                no-jk
# Exclude resources to be processed by RESTful service:
SetEnvIf    Request_URI    "^/backend/"            !no-jk
# Should not be secured and should always return HTTP 200:
SetEnvIf    Request_Method    "OPTIONS"            no-jk
# Fallback value:
SetEnv    http_origin    "*"
SetEnvIf    Origin        "^https?://(localhost|.*\.mycompany\.org)(:[0-9]+)?$" http_origin=$0

Header    set Access-Control-Allow-Credentials    "true"
Header    set Access-Control-Allow-Origin        "%{http_origin}e"
Header    set Access-Control-Allow-Methods    "GET,POST,PUT,DELETE"
Header    set Access-Control-Allow-Headers    "Content-Type,Accept"

JkMount /* loadbalancer

How to POST file input using CORS?

Suppose there is HTML form with <input type="file" id="file-input" /><textarea id="text-input" /> elements. How to send the data of these two fields in one HTTP POST using CORS and jQuery?

The steps for implementation are:
  • The data need to be submitted as multipart/form-data – this is the only way to represent different types of flavours in in request.
  • In Javascript the data should be assembled using FormData() class.
  • jQuery contentType option should be set to false so that jQuery does not attempt to auto-detect request content type.
  • Request headers should not contain Content-type.

code sample

var formData = new FormData();
 
var textInput = $('#text-input');
 
if (textInput.val().length > 0) {
    formData.append('listing-data', new Blob([textInput.val()], { type: "text/plain" }));
}
 
var fileInput = $('#file-input');
 
// fileInput[0] will dereference jQuery object and turn it to DOM object:
if (fileInput[0].files.length > 0) {
    formData.append('file-data', fileInput[0].files[0]);
}
 
jQuery.ajax({
  url:        "...",
  type:        "POST",
  contentType:    false,
  data:        formData,
  ...
});

That generates request something like that:

POST ... HTTP/1.1
Content-Type: multipart/form-data; boundary=71132861028891
X-Requested-With: XMLHttpRequest
Content-Length: 461

--------------------------71132861028891
Content-Disposition: form-data; name="plain-text"; filename="blob"
Content-Type: text/plain

... text ...
--------------------------71132861028891
Content-Disposition: form-data; name="file-data"; filename="input.zip"
Content-Type: application/octet-stream

... binary data ...

References:

JavaScript and Maven

See also:

At the end of the day I would like to come to some ecosystem, which allows to see what version of library is used by a particular project.

For example: myproject:1.1 → mylibrary:0.1 → jquery:1.7.2

The corresponding artefacts should be somehow packaged and deployed to Nexus in usual way and then included into end applications. I think that solution based on Maven is the simplest to approach. In relation to that I have explored few possibilities.

Based on js-import-maven-plugin

:ADD: Pros:

  • This plugin provides the ready-to-use lifecycle for project (jslint, webminifier, js-testrunner).
  • Plugin defines the standard directory tree (src/main/js).
  • Automatic resolution of libraries and dependencies in HTML file, thus the expression
    <script type="text/javascript" src="${index.js}"></script>
    <code>
        is converted to:
        <code html>
    <script src="2-min.js" type="text/javascript"></script><script src="1-min.js" type="text/javascript"></script>

:DEL: Cons:

  • Plugin requires that certain resources are present (src/main/resources/index.html), even if not necessary.
  • The dependencies should be written in JavaScript itself which means that library should be AMDfied:
    /*global define */
    define("xdm", function() {
          return window.xdm;
    });
  • Requirements optionally can also be expressed in JavaScript:
    /*global define, window */
    require([ "jquery" ], function($) {
          $("p").click(function() {
                window.console.log("p clicked");
          });
    });
  • Above means that additional dependency (almond.js – the provider of define() and require() functions) is automatically added as JavaScript dependency.
  • The produced artefact is the JavaScript library (jquery-1.7.2.js and jquery-1.7.2-min.js) thus it is not clean how to package e.g. JS+CSS+images.
  • Plugin has not been updated for a while, and collection of JavaScript libraries is frozen on year 2012 which means that newer libraries should be packaged additionally (if necessary).
  • Few bugs are come across (MJSIMP-11, MJSIMP-6).

Generally js-import-maven-plugin provides the functionality of build-time dependency checking (which is good), but also requires some run-time code (which is not good in my opinion).

Based on WebJars

This approach does not provide any particular plugin for project lifecycle, which opens the doors to the variety of means by which the project can be packaged (maven-jar-plugin, maven-assebly-plugin, whatever). However it assumes that resulting artefact is placed under META-INF/resources/webjars/${project.artifactId}/${project.version} so that later it can be served by Web container as static resource.

:ADD: Pros:

  • The collection of already packaged libraries is huge and up-do-date.
  • JavaScript dependencies are described using RequireJS (which is build on top of AMD) but dependencies can either be expressed in POM directly:
    <properties>
          <requirejs>
          {
                "paths": {
                "jquery": "jquery"
          },
                "shim": {
                      "jquery": { "exports": "$" }
                }
          }
          </requirejs>
    </properties>

    or in the resource src/main/resources/webjars-requirejs.js:

    requirejs.config({
      paths: {
        "fullcalendar": webjars.path("fullcalendar", "fullcalendar"),
        "fullcalendar-css": webjars.path("fullcalendar", "fullcalendar")
      },
      shim: { "fullcalendar": [ "jquery" ] }
    });
  • In principle it is possible to use only wrapped-into-jar JavaScript libraries without dependency voodoo.

I haven't explored this approach in such details to catch any Cons, but I am sure they are.

Based on Javascript Maven Tools

programming/javascript/start.txt · Last modified: 2013/08/10 04:08 by dmitry
 
 
Recent changes RSS feed Driven by DokuWiki