3

(Note, I'm using Reagent, Secretary, and Compojure (among others))

I want to create a route /sectest/:id, and if I point my browser to that route, I get the following error:

Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:3449/sectest/css/site.css". asdf:1 Refused to execute script from 'http://localhost:3449/sectest/js/app.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

But if I click on a link in the browser that navigates to that route, it works fine...

Here's the pertinent code:

Client Side:

(secretary/defroute "/sectest/:id" [id]
  (do
    (js/console.log (str "Hi " id))
    (session/put! :current-page #'my-page)))

Server Side:

(defroutes routes
  (GET "*" [] loading-page) ;this anticipates client-side routing only
  (GET "/cards" [] cards-page)
  (resources "/")
  (not-found "Not Found"))

(def app (wrap-middleware #'routes))

So the following link takes me to my-page, and the console prints "Hi asdf" just fine:

[:div [:a {:href "/sectest/asdf"} "SECTEST"]]

But if I type in http://localhost:3449/sectest/asdf, I get an error, and I can't seem to trace it. I suspect it might have something to do with the code trying to find resources located at /sectest, (which it shouldn't), but I can't confirm this or figure out how to work with it... I am new to clojure, so forgive if I'm massively ignorant on some point, any thoughts?

Josh.F
  • 3,666
  • 2
  • 27
  • 37

1 Answers1

3

Take a look at your server side routing, effectively you only have one route:

(GET "*" [] loading-page)    

As it handles everything all following routes will never trigger. Order matters:

(defroutes routes
  (GET "/cards" [] cards-page)
  (resources "/")
  (GET "*" [] loading-page) ;this anticipates client-side routing only
)

The above should do the trick, I removed the 404 route, as this should be handled by the frontend routing.

The reason it currently works when clicking on a page link in your SPA is that it will get handled by secretary. If you enter the url manually you are doing a page reload and the request is handled by compojure initially.

Edit:

After taking a closer look, relative links to your css/js files in your html template are most likely the culprit here:

/sectest/js/app.js

The compojure resources route won't match and the default catch all route loading-page is served as css/js file to your browser. Hence the error.

For my dev env I also had to correct the :asset-path of my boot cljs task as the source mapping files suffered from the problem. Should be similiar with lein-figwheel.

Erik Dannenberg
  • 5,716
  • 2
  • 16
  • 21
  • Hm, I tried it out exactly as you say, and unfortunately, I get the same behavior, and the same error listed in the beginning of the question... It sounds like your answer is along the right lines (as far as compojure/secretary being the one to handle things), but I don't know how to get compojure to behave with secretary, any other thoughts? – Josh.F Jan 21 '16 at 18:05
  • I'd try using a url prefix with secretary first to ensure everything else is proper. Can't really think of anything else besides your code changes not being active for some reason. – Erik Dannenberg Jan 21 '16 at 21:09
  • I'll try this, and I was just about to write back the following: Here's a case where I get the same error, and I'd think it should work: `(GET "/:id" [id] id)`. If I navigate to "/hello", the browser shows "hello". If I nav to "/hello/world", I get the error that I show in the beginning. Related? – Josh.F Jan 21 '16 at 21:12
  • Using URL prefixes didn't change anything, I still can't figure this out though! I just had a weird bug where I made a route `(defn catchall-page [] [:p "Hola!"])` & `(secretary/defroute "*" [] (session/put! :current-page #'catchall-page))` and if I navigate to some random route, The browser shows "Hola!", but then when I click anywhere, I'm sent back to the main page defined at route "/", but the URL in the browser stays the same (ie some random route)... Am I crazy? – Josh.F Jan 21 '16 at 22:24
  • Regarding `(GET "/:id" [id] id)`, this will only match some string until the next `/`, so the behaviour you are seeing is correct and not related. Made me actually try out some things though and turns out my little pet spa project suffered from the same problem. Updated the answer. :) – Erik Dannenberg Jan 21 '16 at 22:43