Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Сохранение файла при нажатии на кнопку (https://javascript.ru/forum/node-js-io-js/74586-sokhranenie-fajjla-pri-nazhatii-na-knopku.html)

dakociha 23.07.2018 00:45

Сохранение файла при нажатии на кнопку
 
Есть код:
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
	<select id="list">
		<option>a.html</option>
		<option>b.html</option>
	</select>
	<br>
	<textarea id="file" style="width: 100%; height: 300px"></textarea>
	<br>
	<button onclick="save()">Save</button>
</body>

Сервер запущен. При переходе на страницу я выбираю файл, изменяю его и нажимаю сохранить. Вопрос :как сделать, чтобы при нажатии кнопки сохранить файл перезаписывался на значение в textarea

Rise 23.07.2018 05:14

Отправить textarea.value на сервер, через форму (с перезагрузкой страницы) или аякс (без перезагрузки), а там перезаписать.

dakociha 23.07.2018 12:31

Цитата:

Сообщение от Rise (Сообщение 490649)
Отправить textarea.value на сервер, через форму (с перезагрузкой страницы) или аякс (без перезагрузки), а там перезаписать.

Я пишу:
<body>
	<form method="post" action='/a.html'>
		<select id="list" name='select'>
			<option>a.html</option>
			<option>b.html</option>
		</select>
		<br>
		<textarea id="file" style="width: 20%; height: 200px" name='file'></textarea>
		<br>
		<button type="submit">Save</button>
	</form>
</body>

app.post('/a.html', function(req, res) {

  res.send(req.body.file);  //Undefined


});

Выскакивает ошибка: Cannot read property 'file' of undefined

SuperZen 23.07.2018 12:51

по дефолту express (v4) не парсит post request, и поэтому нужен middleware bodyparser

https://github.com/expressjs/body-parser

dakociha 23.07.2018 13:26

app.use(bodyParser.json())
app.post('/a.html', function(req, res) {
  res.send(req.body.file);  //Undefined
})

Undefined все равно

Audaxviator 23.07.2018 16:23

Вообще-то, в вопросе написана какая-то бессмыслица, белиберда - я три раза перечитал, но так ничего и не понял. Про что на него дают ответы - тоже не понял.

destus 23.07.2018 16:31

Audaxviator,
точно бред какой-то)) думал там обычная отправка файла на сервер, оказалось все сложнее.

dakociha 23.07.2018 16:39

Крч. Есть 2 файла в папке. Выбираем допустим файл 'a.html'. В textarea появляется текст из этого файла. Мы изменяем и нажимаем кнопку Save. И вот как сделать, чтобы при нажатии Save текст в textarea перезаписывался в этот файл.
Если еще проще:возможность перезаписать файл

Audaxviator 23.07.2018 17:36

Ну делов-то.
Надо на событие 'change' отправить AJAX-запрос на сервер, оттуда прислать строку выбранного файла и ответ вставить в поле textarea.
Как это сделать - вот сюда https://learn.javascript.ru/

destus 23.07.2018 17:40

dakociha,
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
Потому что когда вы отправляете форму на сервер Content-type: application/x-www-form-urlencoded, а не application/json, как нужно для bodyParser.json()

dakociha 23.07.2018 17:40

Сделал таким образом
app.post('/', function(req, res) {
  fs.writeFileSync(path.join(__dirname, 'public') + '/' 
      + req.body.list, req.body.file);
  res.redirect('back');
});

dakociha 23.07.2018 17:43

Но теперь вопрос.Как достать названия файлов из директории и добавить их в <select>
При выборе файла его содержимое должно показываться в textarea

SuperZen 23.07.2018 17:56

var express = require("express")
var app = express()
var bodyParser = require("body-parser")
var fs = require('fs')

app.use(bodyParser.json())

app.get('/file/:name', function (request, response) {
  var content = ''
  if (fs.existsSync(request.params.name)) {
    content = fs.readFileSync('./' + request.params.name)
  } else {
    fs.appendFileSync('./' + request.params.name, request.params.name)
    content = fs.readFileSync('./' + request.params.name)
  }
  response.send(content)
})

app.post('/file/:name', function (request, response) {
  console.log(request.body)
  fs.writeFileSync('./' + request.params.name, request.body.content)
  response.send(fs.readFileSync('./' + request.params.name))
})

app.get('/', function (request, response) {
  response.send(`<html>
    <head>
      <meta charset="UTF-8">
      <title>Task39</title>
      <script>
        window.addEventListener('load', function() {
          console.log('loaded')
          var list = document.getElementById('list')
          list.addEventListener('change', function(e) {
            loadFile(e.target.options[e.target.options.selectedIndex].innerText)
          })
          loadFile(list.options[list.options.selectedIndex].innerText)
        })

        loadFile = (filename) => {
          fetch('/file/' + filename).then(r => r.text()).then(r => document.getElementById('file').value = r)
        }

        save = () => {
          var list = document.getElementById('list')
          fetch('./file/' + list.options[list.options.selectedIndex].innerText, 
            { 
              method: 'post', 
              body: JSON.stringify({ content: document.getElementById('file').value }),
              headers: new Headers({'content-type': 'application/json'}),
            }
          )
        }
      </script>
    </head>
    <body>
      <select id="list">
        <option>a.html</option>
        <option>b.html</option>
      </select>
      <br>
      <textarea id="file" style="width: 20%; height: 200px"></textarea>
      <br>
      <button onclick="save()">Save</button>
    </body>
  </html>
  `)
})

app.listen(2999, function () {
  console.log("Started on PORT 2999");
})


) схематично,...

dakociha 23.07.2018 18:03

Спасибо

dakociha 23.07.2018 18:49

Все файлы лежат в app.use(express.static(path.join(__dirname, 'public')));.
В папке public у меня есть папка test.Вопрос: как считать все имена файлов из /public/test/ и добавить в <option>
Как при запуске сервера заполнить option в select(у меня есть массив с именами файлов)

Alexandroppolus 23.07.2018 19:03

Цитата:

Сообщение от dakociha
writeFileSync

это очень, очень, очень грустно..

SuperZen 23.07.2018 21:34

Alexandroppolus,
как по твоему правильно?
var express = require("express")
var app = express()
app.get('/file/:name', (request, response) => {
//
})
app.listen(2999, function () {
 console.log("Started on PORT 2999")
})

или
(function() {
var express = require("express")
var app = express()
app.get('/file/:name', (request, response) => {
//
})
app.listen(2999, function () {
 console.log("Started on PORT 2999")
})
})()


или другой пример

Alexandroppolus 23.07.2018 21:47

синхронные операции ввода/вывода катастрофически противопоказаны, если это сервер. Теряется основной замысел ноды, получается хрень.

вот если нода используется локально на компе, например как инструмент для сборки проекта (да вообще как любая тулза с запуском в консоли), то да, ***Sync удобно и просто.

Цитата:

Сообщение от SuperZen
как по твоему правильно?
или ... или

без разницы. В нодовских модулях всё локально, в глобальный объект не попадает


Часовой пояс GMT +3, время: 22:58.