0

Solution:

I should have spotted this earlier. Anyone following the book (or something similar) may be helped by this:

I had put the files under the wrong "static" directory: [project directory]/static, rather than [project directory]/lists/static, where "lists" is the name of the created Django "app". I was misled by the fact that there was a base.css file (which was being loaded) in both these "static" directories.


I'm trying to learn Django from a (very good) book.

It's just got to the chapter where some Javascript is being added. I am not really a newb when it comes to Javascript.

But I've hit the complete buffers with this.

We are told to put these lines towards the end of our Django template file base.html:

<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/list.js"></script>

<script>
  initialize(); // NB this is a simple function in the list.js script
</script>

NB for clarification, I am running this in a browser using the Django Development server. The functional tests which fail, contrary to what the book says should happen, are using django.contrib.staticfiles.testing.StaticLiveServerTestCase.

All the browsers I've tried (Firefox, Chrome, Opera) fail to load these JS files. In the case of Chrome (console) I get Status 404 for these two files, whereas two .css files in/under the same directory get Status 200. In the case of FF (v. 72) the console messages are slightly more cryptic: for both files the console first gives a baffling MIME-related message: "The script from “http://localhost:8000/static/jquery-3.3.1.min.js” was loaded even though its MIME type (“text/html”) is not a valid JavaScript MIME type." and then immediately afterwards says "Loading failed for the with source “http://localhost:8000/static/jquery-3.3.1.min.js."

I have done quite a bit of searching to find out what might be going on. I have tried lines like this in the Django template file in question:

<script type="text/javascript"  src="/static/jquery-3.3.1.min.js"></script>

<script LANGUAGE="JavaScript"  src="/static/jquery-3.3.1.min.js"></script>

<script type="application/javascript"  src="/static/jquery-3.3.1.min.js"></script>

... none of the above change anything.

The Django server I am running also says 404... but only for the JS files:

[19/Apr/2020 18:19:04] "GET / HTTP/1.1" 200 1451
[19/Apr/2020 18:19:05] "GET /static/jquery-3.3.1.min.js HTTP/1.1" 404 1670
[19/Apr/2020 18:19:05] "GET /static/base.css HTTP/1.1" 200 33
[19/Apr/2020 18:19:05] "GET /static/list.js HTTP/1.1" 404 1634
[19/Apr/2020 18:19:05] "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 200 117305
[19/Apr/2020 18:19:05] "GET /static/list.js HTTP/1.1" 404 1634

Suspecting I might be going out of my mind, I double-checked and treble-checked: these precise JS files, with these precise names, are indeed in the "static" directory in question.

I don't understand what this MIME stuff is all about and how it might block the loading of a JS file so dramatically. For what it's worth I checked the MIME types on my machine thus:

mike@M17A ~ $  grep 'js' /etc/mime.types
application/javascript              js
application/json                    json

I find it difficult to believe this is relevant, since I'm getting problems with all 3 browsers, but there is a "Learn more" link with the FF error messages, which leads here, where we read as follows:

Starting with Firefox 72, the opting out of MIME sniffing is also applied to top-level documents if a Content-type is provided. This can cause HTML web pages to be downloaded instead of being rendered when they are served with a MIME type other than text/html. Make sure to set both headers correctly.

Site security testers usually expect this header to be set.

My FF version? Yes, 72.

How does one actually "set a header"? Not that this is necessarily the solution ... but it presumably can't hurt.

Edit following Sraw's comment
Chrome dev tools headers for jquery-3.3.1.min.js:

General
    Request URL: http://localhost:8000/static/jquery-3.3.1.min.js
    Request Method: GET
    Status Code: 404 Not Found
    Remote Address: 127.0.0.1:8000
    Referrer Policy: no-referrer-when-downgrade
Reponse Headers
    Content-Type: text/html
    Date: Sun, 19 Apr 2020 18:36:11 GMT
    Server: WSGIServer/0.2 CPython/3.6.10
Request Headers
    Accept: */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
    Cache-Control: no-cache
    Connection: keep-alive
    Cookie: csrftoken=Nhj1OavzFCQ3HYRmpWIdSlR595Y6hHGprY2sMUkLL5wzuIIDw1PjTx9fUfpVDnU8
    Host: localhost:8000
    Pragma: no-cache
    Referer: http://localhost:8000/
    Sec-Fetch-Mode: no-cors
    Sec-Fetch-Site: same-origin
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
mike rodent
  • 14,126
  • 11
  • 103
  • 157
  • Could you share the response information in your dev tools? I mean the F12 gives to you in Chrome and the similar thing in FF. All the headers would be helpful. – Sraw Apr 19 '20 at 18:29
  • Thanks. Sorry to be utterly obtuse, but what exactly are you asking me to do? In both Chrome and FF, F12 appears to toggle the dev tools. When you say "headers"... where do I get and report on those from in the dev tools? – mike rodent Apr 19 '20 at 18:33
  • Click "Network" in the dev tools and choose one request, such as your "jquery-3.3.1.min.js", then you can see the details such as Headers, Preview Response, Initiator, etc. The most useful part is Headers. If you can share the "Response Headers", it would be helpful to debug. – Sraw Apr 19 '20 at 18:35
  • Thanks, see edit... – mike rodent Apr 19 '20 at 18:41
  • So it is not hard to see that the "Content-Type" is not correct, basically it should be something like "text/javascript" or "application/javascript". I think it should be a server-side problem that returns the wrong results. As there is no Django code in your question, I cannot tell more but here is one related question which may solve your problem: https://stackoverflow.com/questions/11811256/how-to-set-content-type-of-javascript-files-in-django – Sraw Apr 19 '20 at 18:50
  • Thanks. There's a bit to go on in that question. I tried the urls.py pattern to views.java_script described by the OP but that didn't work. The chosen answer in a linked question says "You need to configure the server to send a JavaScript response with Content-Type: application/javascript"... how does one actually do that in Django? Also I don't quite understand how a meaningful response concerning content-type can be given if the response code is 404... is this based purely on the .js extension in the request? Baffled. As I say, I'm a Django newb. – mike rodent Apr 19 '20 at 19:11
  • Seems like the files are not in the correct location. I notice that your URLs use `/static` while the chapter you linked to uses `../`. See [the documentation](https://docs.djangoproject.com/en/3.0/howto/static-files/#configuring-static-files) for the proper place to put static files so they are seen by the web server. You should probably add your static file settings here, as well as the actual directory locations of the files. – Kevin Christopher Henry Apr 19 '20 at 23:10
  • @KCHenry Thanks. How much of that chapter did you look at? When testing the JS file in isolation the path is indeed `../`, but when the ` – mike rodent Apr 20 '20 at 06:21

1 Answers1

0

Posting this as an answer. Despite my embarrassment at making such a stoopid-level mistake.

I had put the files under the wrong "static" directory: [project directory]/static, rather than [project directory]/lists/static, where "lists" is the name of the created Django "app". I was misled by the fact that there was a base.css file (which was being loaded) in both these "static" directories.

I propose accepting this answer to keep the question, on the grounds that someone may be helped in future as one of several reasons why there may be problems loading JS files.

If enough people vote to close instead I shall delete everything!

mike rodent
  • 14,126
  • 11
  • 103
  • 157