LINUX.ORG.RU

В Web-проекте под Cowboy не видятся JS-скрипты

 , , ,


0

1

Для сборки использую relx. Операционка - Debian 10, версии Erlang, Cowboy, rebar и т.д. самые свежие. Проблема в том, что после открытия страницы сайта получаю ошибки на подключаемые скрипты, хотя они лежат там же, рядом с индексной страницей. Права на файлы - пользовательские. Запуск приложения с правами пользователя. Страница работает нормально, кроме загрузки скриптов.

Скрипты подключаю в index.html как обычно

<script src=«jquery.min.js»></script>

Ошибка такая «Failed to load resource: the server responded with a status of 404 (Not Found)»

Или такая «http://127.0.0.1:8080/jquery.min.js net::ERR_ABORTED 404 (Not Found)»

Почему не видятся скрипты?



Последнее исправление: Vahmurka (всего исправлений: 1)
Ответ на: комментарий от ddidwyll

Я его кажется не менял вообще. А надо?

%% Feel free to use, reuse and abuse the code in this file.

%% @private -module(upload_app). -behaviour(application).

%% API. -export([start/2]). -export([stop/1]).

%% API. start(_Type, Args) -> Dispatch = cowboy_router:compile([ {’’, [ {«/», cowboy_static, {priv_file, upload, «index.html»}}, {«/upload», upload_h, []} ]} ]), {ok, _} = cowboy:start_clear(http, [{port, 8080}], #{ env => #{dispatch => Dispatch} }), upload_sup:start_link().

stop(_State) -> ok = cowboy:stop_listener(http).

Vahmurka
() автор топика
{"/assets/[...]", cowboy_static, {dir, "/absolute/path/to/folder/with/js"}}
<script src="/assets/your.js">...</script>

Вот так будет работать.

ddidwyll ★★★★
()
Ответ на: Я его кажется не менял вообще. А надо? от Vahmurka

А надо?

Ну посмотри внимательно на код, где там роут к чему-нибудь кроме index.html и /upload?

На всякий случай, у ковбоя отличная документация, советую почитать.

ddidwyll ★★★★
()
Последнее исправление: ddidwyll (всего исправлений: 1)
Ответ на: комментарий от ddidwyll

Понял попробую. Попробовал относительный путь, получаю туже ошибку.

Прям абсолютный путь писать надо? Не слишком ли кондово?

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

Попробуй абсолютный чтобы исключить другие ошибки, если не будет работать почитай доку или на худой конец google: cowboy serving static files and directories examples, мне если честно лень за тебя это делать, да иковбой я видел несколько лет назад последний раз. Если ничего не поможет возвращайся, расскажешь что делал и что не получилась, разберёмся вместе.

ddidwyll ★★★★
()
Ответ на: комментарий от ddidwyll

Всё таки сам посмотрел,

{"/assets/[...]", cowboy_static, {priv_dir, upload, "static/assets"}}
сделай
mkdir -p priv/static/assets/js
mv your.js prive/static/assets/js
и your.js станет доступен по http://localhost:8080/assets/js/your.js

И ещё, вроде припоминаю, что надо было дёргать перекомпиляцию роутов после каждого их изменения, но я использовал ковбой из эликсира, хз как там в эрланге, перекомпилирует он их сам или нет.

ddidwyll ★★★★
()
Последнее исправление: ddidwyll (всего исправлений: 1)
Ответ на: комментарий от ddidwyll

Попробовал абсолютный путь. А именно, в корне файловой системы создал симлинк assets на папку assets, к которой длииииииинный и очень случайный путь

Роут выглядит так {«/assets/[…]», cowboy_static, {dir, «/assets»}},

Скрипты загрузились, проблема решена, но мне это решение не нравится - слишком кондово. В продакшене придется новый симлинк создавать на неизвестный путь.

Пойду читать, зачем такое сотворили. Спасибо за помощь!

Есть еще вопрос, связанный с путями.

Приложение, использующее cowboy находится в глубине дерева релиза _rel, там может быть много других приложений. Однако, при аплоаде файлов они попадают в корень _rel, а не в какую либо из папок приложения, которое его создало - не в корень и не в подпапку upload. Таким образом, в корне _rel будут валяться файлы, которые хотелось бы разместить совсем в другом месте.

Указание пути в имени передаваемого файла приводит к неработоспособности приложения.

Например такие имена «/upload/файл.png» приводят к ошибке, а не к сохранению файла в папке /upload

Vahmurka
() автор топика
Ответ на: комментарий от ddidwyll

Новый ответ не видел. Спасибо за ответ!

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

продолжение

Вот код в приложении, где полученный файл сохраняется на сервере.

Filepath = Filename, file:write_file(Filepath, Data),

Я практически ничего не менял относительно примера, только Filename вынес из параметров, чтобы путь указать.

Любое изменение Filepath, отличное от приведеного приводит к ошибке. Такое ощущение, что функция file:write_file не умеет писать файлы с путями как есть, полагаясь на операционную систему.

Многие другие средства Linux такой особенности не имеют.

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

Есть еще вопрос, связанный с путями.

Я не в курсе как оно там в эрланге и его тулах устроено, но логикак кмк такая, если ты указываешь абсолютный путь в роуте - он там и будет, если относительный - то он будет относителен той директории в которой запускается приложение, {priv_dir, upload, «path»} - говорит что надо искать «path» в директории priv приложения upload, запись {«/upload», upload_h, []} - по логике передаёт управление роутами подходящими под «/upload» в upload_h, значит в upload_h должна быть своя обработка роутов, попробуй в код upload_h посмотреть как туда можно передать путь куда будут падать загружаемые файлы или просто руками поправь. Передать попробовать можно с помощью конструкции {PathMatch, Constraints, Handler, InitialState}, где PathMatch - «/upload», Handler - upload_h

в корне _rel будут валяться файлы

Директория upload, в которую падают загрузки должна быть только в priv, иначе тебе туда накидают всякого нехорошего.

Я могу ошибаться, основной совет - покури код upload_h и https://ninenines.eu/docs/en/cowboy/2.7/guide/routing/

ddidwyll ★★★★
()
Ответ на: комментарий от ddidwyll

Я привел строчку из upload_h, отвечающую за запись полученного по сети файла на диск. Там уже нет роутинга, там должно быть возможно указывать любой путь. Я прописывал конкатенацию строк имени файла и отностительного пути

Filepath = «upload/» ++ Filename,

и другими способами тоже пробовал и константой указывать имя файла с путем пробовал.

получалось «upload/имя.png». Функция write_file в таком случае ничего никуда не сохраняет. Я бы рад поменять путь, но при попытке что либо изменить функция не работает.

Подпапку upload я создал в двух местах priv/upload и _rel/upload при указании пути Файл не попадает никуда.

Без пути, файл попадает в _rel

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

в таком случае ничего никуда не сохраняет.

Что значит ничего не сохраняет? Добавь вывод результата работы write_file куда-нибудь и посмотри что за ошибка

Filepath = «upload/» ++ Filename

Попробуй что-то вроде file:get_cwd() ++ «/priv/» ++ Filename, а где-нибудь раньше по коду какой-нибудь принт того что выдаёт file:get_cwd()

Сорри я эрланг не знаю, вряд ли смогу помочь, cast AUX loz sergej ubuntu

ddidwyll ★★★★
()
Ответ на: комментарий от ddidwyll
  1. Запускаю приложение в отладочном режиме. Когда есть ошибки оно выдает их в консоль. Но в случае с указанием пути, никаких ошибок не выдается. Просто ничего не происходит.

  2. Нет никаких указаний, что функции write_file требуется путь, а значит необходимость get_cwd() и priv под вопросом. Я могу просто константой написать любой путь, хоть полный от корня, хоть относительный, хоть к priv хоть куда, с любым именем и будет тоже самое.

  3. Чистое имя файла, которое я получаю в обработчик, также само по себе является относительным путем, просто путь у него нулевой. И ничего, пишется нормально. Значит относительность пути не причем.

Конкатенация тут не причем и конкретный путь не причем.

Vahmurka
() автор топика

Ещё чуток подскажу, раз никто не помог, relx - это релиз менеджер он компилит бинарник куда то (твой _rel), если ты запустишь тот бинарник из любой директории кроме той в которой лежит priv (т.е. запустишь что/то/там/_rel/бинарник), то он сможет найти нужный priv только по полному абсолютному пути, потому что относительным будет начинаться с той диретории из которой ты его запускаешь. Например ты сидишь в /home и запускаешь app/_rel/bin/upload, а в коде пытаешься сохранить в upload/file.png, то твой бинарник будет пытаться сохранить в /home/upload/file.png. Тут два пути либо ты запускаешь бинарник (ну и билдишь тоже) из корня проекта, в котором есть priv/download и сохраняешь в priv/download/file.png, но очевидно это не удобно, либо ищешь способ узнать абсолютный путь priv/upload, я погуглил и думаю тебе нужно что-то вроде

Filepath = filename:join([code:priv_dir(upload), "upload", Filename]), file:write_file(Filepath, Data),

ddidwyll ★★★★
()
Ответ на: комментарий от ddidwyll

Непроверенным остался один вариант, что я не экранирую слэши. Однако, нет никаких указаний, что их надо экранировать.

Пока оставил вариант с чистым именем, хоть так работает. Путями потом займусь. Если у кого есть идея, буду благодарен.

Сейчас другими ошибками занимаюсь. У меня передача несуществующего файла (сгенерированого на лету и не сохраненного на диск) и к тому же без формы не получается. Но это тема другого топика, тут неуместно.

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

Нет никаких указаний, что функции write_file требуется путь

Ну подумай, куда сохранится файл без пути?

Чистое имя файла, которое я получаю в обработчик, также само по себе является относительным путем, просто путь у него нулевой. И ничего, пишется нормально. Значит относительность пути не причем.

Ты был близок, только относительность пути тут при чем.

Просто попробуй запустить своё приложение из любого другого каталога, и файл без пути сохраниться в него.

ddidwyll ★★★★
()
Ответ на: комментарий от ddidwyll

Спасибо за ответ. Попробую позже. Но я запускаю проект вот так

make run

из корня папки разработки он цепляет менеджер relx и erlang.mk, который очень большой и не юзерфрендли. Подгружает и компилирует зависимости, копирует всё в _rel, создает архив релиза и запускает приложение в отладочном режиме. Я путями не управляю. В Makefile ничего полезного нет. Поэтому пока ничего по поводу вариантов запуска сказать не могу, не дошел пока до этой стадии. Пока в отладочном режиме и с дефолтными настройками работаю.

Vahmurka
() автор топика
Ответ на: комментарий от ddidwyll

Спасибо, помог! Получилось! Только я переименовал проект, чтобы было понятнее, где имя проекта, а где имя папки.

Filepath = filename:join([code:priv_dir(«upserver»), «upload», Filename]), file:write_file(Filepath, Data),

Файл сохраняется в заранее созданной папке ./priv/upload

Вывод Filepath на консоль Filepath=««/home/user/group/projects/upserver/_rel/upserver/lib/upserver-1/priv/upload/test.png»»

Где Filename=test.png, остальное добавилось этим кодом.

Значит раньше что-то не то было в строке пути, а я не проверял. Честно говоря, константами я только относительные пути задавал, потому и не получалось, если их добавить к тому путю. Так полный путь не проверял, был уверен, что не должно так быть, что движок сам должон полный путь знать.

Тему можно закрывать.

Vahmurka
() автор топика
Ответ на: комментарий от Vahmurka

Рад помочь.

Тему можно закрывать.

Нажми в стартпосте «Отметить как решённую».

ddidwyll ★★★★
()
Ответ на: комментарий от Vahmurka

Например такие имена «/upload/файл.png» приводят к ошибке, а не к сохранению файла в папке /upload

К какой ошибке то приводит?

loz ★★★★★
()
Ответ на: комментарий от loz

Вангую что {error, enoent}, ну или {error, eacces}, и на первых порах в большом выхлопе наверно не просто понять, что это и есть ошибка.

ddidwyll ★★★★
()

Зачем в 2021-м году использовать jQuery?)))

dimuska139 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.