Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

javascript - Why is my EL-statement only working in a script-tag where I do not import a js.file through a src-reference?

I have a javascript file, where I have collected login- and other user profile ajax calls that needs to be available on all of the pages in my web application.

For all of my ajax calls, I need the context path of the webapp to get the correct URL. A baseUrl-variable can be defined by var baseUrl = "${pageContext.request.contextPath}";.

I am experiencing a puzzling error though. If i try to initialize the baseUrl variable inside my login.js-file, it does not work. It is simply set to the string value "${pageContext.request.contextPath}" This .js-file contains all the scripts where I actually need the variable. However, if I define it inside a sourceless script-tag in the .jsp file itself, it works like a charm. (Code in the bottom)

I am guessing that this has something to do with when, and in which scope the expression is compiled and/or executed, and maybe also the difference between dynamic and static imports of code. I just can't wrap my head around exactly what is happening, and why my desired approach, to define the variable within the login.js-file, does not work.

Working import statement:

<script>var baseUrl = "${pageContext.request.contextPath}";</script>
<script src="<c:url value="/js/login.js"/>" type="text/javascript"></script>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

EL expressions are only evaluated by the therefor capable servlets. Examples of such servlets are JSP's JspServlet and JSF's FacesServlet. The one is capable of evaluating ${...} in template text and the other is capable of evaluating both ${...} and #{...} in template text. The container's default servlet who's responsible for static resources like *.js files isn't.

Given that you're using JSP, just tell your webapp to use JspServlet to process any *.js requests. The container's builtin JspServlet has usually a default servlet name of jsp (at least, that's true for Tomcat and clones), so the below entry in your webapp's web.xml should do in order to get EL to be evaluated in *.js files.

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

This has one small caveat though. Some containers forcibly change the content type header to text/html regardless of the js file extension and then browsers got confused while downloading the JS file. One way to prevent that is to explicitly set the desired content type header in top of JS file the JSP way:

<%@page contentType="application/javascript" %>

A completely different alternative would be to print the context path as HTML5 data attribute of the <html> tag.

<!DOCTYPE html>
<html lang="en" data-baseuri="${pageContext.request.contextPath}/">
    ...
</html>

It's then just available anywhere in JS as below:

var baseuri = document.documentElement.dataset.baseuri;

Or if you're a jQuery fan:

var baseuri = $("html").data("baseuri");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...