Задать вопрос
  • Как организовать доступ к ресурсам в REST API?

    gobananas
    @gobananas
    finishhim.ru
    Перемудрили. Всё должно быть очень просто. Что такое тип медиа? Музыка или видео? Так по
    /movies/genre/{id}/film/{id} - фильмы
    /music/albums/{id}/tracks/{id} - музыка

    Далее. Если я знаю id трека или фильма мне надо дать возможность обратиться непосредственно к нему:
    music/track/{id} - всё

    Если я не знаю какой трек мне нужен я прошу все треки из направления музыкального, например rap у него id=13
    music/style/13

    По этому запросу выдаются пачки направления по 100, 300 или 1000 штук в зависимости от ресурсов и можно указать пагинатор
    music/style/13/2 - вторую страницу направлений мне покажите

    Именно поэтому параметры лучше передавать в явном виде в url типа style=13&page=2 потому что так не запутаешься что такое 13 и что такое 2.

    Если я совсем ничего не знаю и жанры тоже должен быть вспомогательный метод для получения всех жарнов, как у ВК для получения городов например. Запрос вида:
    music/allganre?page=0

    отдаёт 100 пар вида "название жарнра -> id" так сделав 5 запросов с page=0/1/2/3/4 я в своём приложении смогу иметь всю базу возможных жанров. Можно сделать метод что бы получить жанр конкретной песни:
    music/getganre?track=1456

    И т.п.
    music/getalbums/1456 - получить все альбомы исполнителя
    music/detailalbum/1456 - получить все данные об альбоме (год выпуска и т.п.)
    music/tracksalbum/1456 - получить список треков конкретного альбома

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

    Astrohas
    @Astrohas
    Python/Django Developer
    $(".cat1").css("background-color", changelogTotals_colors[0]);

    будет вызываться только к тем элементам которые есть в Dom. Для решения вопроса либо после
    $(".popupcontent").append(" <div class=\"changelogCategory cat1\">текст</div>\n" +");
    еще раз вызовите
    $(".cat1").css("background-color", changelogTotals_colors[0]);
    либо используйте дилегерирование.
    Ответ написан
    Комментировать
  • Как сделать бесконечную пробежку по потомкам в vue.js?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Вот прямо из стандартных примеров https://vuejs.org/v2/examples/tree-view.html неделю назад сделал подобное.
    Само дерево, правда, храню в vuex, для чего пример пришлось немного передалать и под свои данные и под свои экшены. Но там несложно, мне как человеку с vue всего две недели :-)
    Получилось примерно так:
    3b4af24d9f374ebea61d6ee22c644f19.png
    Ответ написан
    Комментировать
  • Может кто-то объяснить насчет зависимостей в node_modules?

    fakey0u
    @fakey0u
    (javascript) => ['Node.js', 'React']
    можно написать patch над модулем.

    Каждый модуль в момент require('some-module') попадает в require.cache и далее данный модуль можно пропатчить.
    Например:
    // first.js
    const add = (a,b) => a +b;
    module.exports.add = add
    
    // patched.js
    const MODULENAME = './first';
    const moduleToPatch = require(MODULENAME); // здесь мы кешировали нужный нам модуль
    
    require.cache[require.resolve(MODULETOPATCH)].exports.add = (a,b) => {
     console.log('PATCHED ! ! ! ! ')
     return a + b;
    }
    
    // second.js
    require('./patched');
    const { add } = require('./first');
    
    console.log(add(10, 20)) 
    // PATCHED ! ! ! !
    // 30


    Естественно первым нужно подключать модуль для патча, чтобы он сделал первый require у себя
    Ответ написан
    1 комментарий
  • Как правильно удалить объект в VUEX?

    amux
    @amux
    alp.ac
    mutations:{
        REMOVE_ITEM (state, id) {
          state.items.$remove(id)
        }
    }
    Ответ написан
    Комментировать
  • Как быстро найти необходимые файлы в верстке?

    roamn
    @roamn
    Front-end developer
    Здравствуйте.
    Если проект большой и нет возможности анализа шаблона средствами CMS, то выделяю кусок кода, и делаю поиск по проекту. В работе использую Sublime Text 3.
    Ответ написан
    Комментировать
  • Когда стоит использовать JS Promises?

    Когда кто-нибудь будет читать ваш код и наткнется на then, то будет думать, что это асинхронная операция. Его будет ждать глубокое разочарование и когнитивный диссонанс.
    Ответ написан
    Комментировать
  • Как правильно организовать авторизацию веб-сервиса на Express?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Как на счет jwt ?

    За! Удобно, нравится.

    Вкратце - шлете стандартные регистрационные данные, сервер выдает вам токен. Далее токен добавляете в заголовки запросов.

    В прицнипе, в гугле инфы хватает по вопросу. Сам сайт посмотрите (jwt.io), оттуда ссылка на пакет для node

    Скопирую сюда куски кода из своего api сервера, но скажу сразу - в node я не очень силен, если будут замечания от знающих - только рад. Так же angular кода не приведу, потому что клиентский код у меня на react.

    Здесь в файле используются callbacks, возможно есть варианты получше. В других роутах приложения я где-то через async поигрался, где-то через promise.

    Мой роутер auth

    const express = require('express')
    const router = express.Router()
    const User = require('../models/user')
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    
    router.post('/signup', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.hashPassword(req.body.password, (err, passwordHash) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
    
          const user = new User({
            name: req.body.name,
            nickname: req.body.nickname,
            email: req.body.email,
            password: req.body.password,
          })
    
          user.passwordHash = passwordHash
          user.save((err, item) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            const payload = {
              _id: item._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    router.post('/signin', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
      const password = req.body.password
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.findOne({ email: req.body.email }, (err, user) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
          if (!user) {
            return res.status(400).json({ error: 'User not found' })
          }
          User.comparePasswordAndHash(password, user.passwordHash, (err, areEqual) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            if (!areEqual) {
              return res.status(400).json({ error: 'Wrong password' })
            }
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    module.exports = router;


    Модель user

    const mongoose = require('mongoose')
    const bcrypt = require('bcrypt')
    const Schema = mongoose.Schema
    let bcrypt_cost = 12
    
    const userSchema = new Schema({
      name: { type: String, required: true },
      email: { type: String, required: true },
      passwordHash: String,
    })
    
    userSchema.statics.hashPassword = (passwordRaw, cb) => {
      if (process.env.NODE_ENV === 'test') {
        bcrypt_cost = 1
      }
      bcrypt.hash(passwordRaw, bcrypt_cost, cb)
    }
    
    userSchema.statics.comparePasswordAndHash = (password, passwordHash, cb) => {
      bcrypt.compare(password, passwordHash, cb)
    }
    
    const User = mongoose.model('User', userSchema)
    
    module.exports = User


    В коде роутера есть AUTHO_CLIENT - так как я изначально брал реализацию от AUTH0, кстати, может понравится? У них удобно все... Но для себя в целях обучения переписал на свою. (какая-то ссылка у них про angular cookies vs token)

    Мне нравится, что некоторую информацию я могу взять прямо из токена (например, уровень доступа - в моем примере - poll)
    Ответ написан
  • Почему затираются мои изменения по коду при merge?

    2ord
    @2ord
    Скорее всего, код был затёрт при разрешении конфликта тем кто его разрешал.
    Ответ написан
    Комментировать
  • Как получить data из vue компонента в другом компоненте?

    @kristenstewartdadada
    Frontend Developer
    используйте store для хранения данных, очень удобно!
    Ответ написан
    1 комментарий
  • Как запилить совместный проект кодеру и сисадмину для практики?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Например написать простейший мессенджер/чат с балансировкой нагрузки, бэкапами, сервероми приложений/БД, масштабированием и всеми необходимыми сервисами и плюшками.

    UPD: А еще добавлю такой вариант: присоединиться к какому-нибудь OpenSource проекту.
    Ответ написан
    Комментировать
  • Как найти нужный файл через терминал linux, зная, что файл содержит слово?

    icCE
    @icCE
    youtube.com/channel/UC66N_jRyZiotlmV95QPBZfA
    Боюсь надо будет писать скрипт, который будет распаковывать архивы. Увы но без этого не как.
    Все остальное решается grep,egrep,awk или find.

    grep -lir 'text' /home/%username%/doc
    Ответ написан
    2 комментария
  • Как в vuejs передать параметры компоненту через роутинг?

    Fragster
    @Fragster
    помогло? отметь решением!
    <router-view :prop="var"> работает, но вообще, если такой вопрос возникает, то я бы смотрел в сторону vuex
    Ответ написан
    Комментировать
  • Как правильней обрабатывать POST запросы в Node.js?

    @RidgeA

    Вопрос. Можно ли реализовать запросы к одной и той же странице, и как мне на серверной стороне проверять, с каким я запросом работаю?

    Можно. Только зачем?

    ИМХО после регистрации лучше возвращать 302 статус и редирект на страницу логина. Либо то же самое делать на фронтэнде, если SPA
    router.post('/register', 
     userController.validateRegister,
     userController.register,
     authController.login
    )
    Ответ написан
    2 комментария
  • Как достать следующий элемент массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function* cyclicSequence(items) {
      for (var i = 0; ; i = (i + 1) % items.length) {
        yield items[i];
      }
    }
    
    var color = cyclicSequence([ 'green', 'red', 'blue', 'yellow' ]);
    
    $('#typeProject').click(function() {
      $('.typeProject').css('background-color', color.next().value);
    });
    Ответ написан
    3 комментария
  • Отправляю метод put шлет options?

    Fragster
    @Fragster
    помогло? отметь решением!
    Почему не работает axios.put + expressjs?
    Сервер должен возвращать заголовок Access-Control-Allow-Methods
    Ответ написан
  • Какова ответственность vuex action?

    kulakoff
    @kulakoff
    Vue.js developing
    Компоненты вызывают экшены чтобы перейти в определённое состояние. Экшены взаимодействуют с сервисами, которые дают необходимые данные для изменения состояния.
    Управление локалью можно рассматривать как сервис. Поэтому имхо все нормально.
    Ответ написан
    Комментировать
  • Axios отправляет post шлет options?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    • Если метод – не GET / POST / HEAD.
    • Если заголовок Content-Type имеет значение отличное от application/x-www-form-urlencoded, multipart/form-data или text/plain, например application/xml.
    • Если устанавливаются другие HTTP-заголовки, кроме Accept, Accept-Language, Content-Language.

    …Любое из условий выше ведёт к тому, что браузер сделает два HTTP-запроса.

    Первый запрос называется «предзапрос» (английский термин «preflight»). Браузер делает его целиком по своей инициативе, из JavaScript мы о нём ничего не знаем, хотя можем увидеть в инструментах разработчика.

    Этот запрос использует метод OPTIONS. Он не содержит тела и содержит название желаемого метода в заголовке Access-Control-Request-Method, а если добавлены особые заголовки, то и их тоже – в Access-Control-Request-Headers.

    Его задача – спросить сервер, разрешает ли он использовать выбранный метод и заголовки.
    https://learn.javascript.ru/xhr-crossdomain

    Как видите, дело в том, что вы не указали заголовок Content-Type.

    Следом за этим запросом должен идти POST-запрос, если сервер ответил, что всё ок (в вашем случае похоже на то).
    Ответ написан
    2 комментария