Подтвердить что ты не робот

Облачные функции для Firebase: "Ошибка: не удалось обработать запрос"

Мне хочется вытащить волосы; это либо супер просто, и у меня есть замораживание мозга, или это не так просто.

Что я хочу

Я пытаюсь отключить сокращенный URL-адрес с помощью firebase, когда пользователь переходит к:
myapp.firebaseappurl.com/url/SHORTENEDLINK
SO не позволит мне добавить сокращенный URL

Я хотел бы, чтобы результат был:

{
  "url": "https://stackoverflow.com/info/45420989/sphinx-search-how-to-use-an-empty-before-match-and-after-match"
}

Что я пробовал

firebase.json файл:

{
  "hosting": {
    "public": "public",
    "rewrites": [ {
    "source": "/url/:item",
      "destination": "/url/:item"
    } ]
  }
}

index.js файл:

const functions = require('firebase-functions');

exports.url = functions.https.onRequest((requested, response) => {

    var uri = requested.url;
    request({
        uri: uri,
        followRedirect: true
      },
      function(err, httpResponse) {
        if (err) {
          return console.error(err);
        }
        response.send(httpResponse.headers.location || uri);
      }
    );

});

Результат

Когда я перехожу к myapp.firebaseappurl.com/url/SHORTENEDLINK, я получаю следующее:

Error: could not handle the request
4b9b3361

Ответ 1

Вы пытались использовать синтаксис { source: '/url/**' }?

Вы можете использовать что-то вроде этого:

{
  "hosting": {
    "public": "public",
    "rewrites": [ {
    "source": "/url/**",
    "function": "/url"
    }]
  }
}

а затем вы можете проанализировать URL-адрес из запроса.

 exports.url = functions.https.onRequest((req, res) => { 
   // parse the url from the req and redirect to the correct link
 });

Ответ 2

Вы видите Error: could not handle the request, поскольку, вероятно, было исключение и оно было отключено.

Проверьте свои журналы, используя:

firebase functions:log

Подробнее см. docs

Вот как я получил URL-адрес без искажений для работы

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const http = require('http');
const urlP = require('url');

const unshorten = (url, cb) => {
  const _r = http.request(
    Object.assign(
      {},
      urlP.parse(url),
      {
        method: 'HEAD',
      }
    ),
    function(response) {
      cb(null, response.headers.location || url);
    }
  );
  _r.on('error', cb);
  _r.end();
};

const resolveShortUrl = (uri, cb) => {
  unshorten(uri, (err, longUrl) => {
    if (longUrl === uri) {
      cb(null, longUrl);
    } else {
      resolveShortUrl(longUrl, cb);
    }
  });
};

exports.url = functions.https.onRequest((requested, response) => {
  var uri = requested.query.url;
  resolveShortUrl(uri, (err, url) => {
    if (err) {
      // handle err
    } else {
      response.send({ url });
    }
  });
});

Вы можете сразу же последовать примеру hello world и использовать приведенный выше код как ваш function.

В приведенном выше коде используются запросы HEAD, чтобы заглянуть в поле "Местоположение" заголовков и решает, может ли URL-адрес еще больше не сокращаться.

Это легче, так как запросы HEAD не требуют никакого тела (таким образом избегая разбора тела). Кроме того, никакой третьей стороне lib не требуется!

Также обратите внимание, что URL-адрес передан как параметр запроса. Таким образом, запрос будет

http://<your_firebase_server>/url?url=<short_url>

Сохраняет проблемы с повторной записью URL. Плюс семантически имеет смысл.

Ответ 3

Я думаю, что ваш код в порядке. То, что вы делаете неправильно, заключается в том, что вы используете обозначения Express-js в firebase.json rewrites node. (часть :item). Они не работают в базе данных Firebase Realtime.

Итак, вместо этого измените firebase.json на следующее: -

 {
  "hosting": {
    "public": "public",
    "rewrites":  {
    "source": "YOUR SHORTENED URL",
    "destination": "YOUR ORIGINAL URL"
  } 
  }
}

Это также защищенный подход в облачных функциях для Shortcut Shortbase URL sample.

Ответ 4

Сначала убедитесь, что вы правильно получили запрос с укороченным URL-адресом.

const functions = require('firebase-functions');

const express = require('express');
var express_app = express();
express_app.use(body_parser.text({type: ()=>true}));
express_app.all('*', (req, res) => {
    console.log(req.path);
    res.send(JSON.stringify(req.path));
});
exports.url = functions.https.onRequest(express_app);

Теперь, когда вы посещаете myapp.firebaseappurl.com/url/SHORTENEDLINK, вы должны увидеть SHORTENEDLINK в виде обычного текста. Когда это работает, попробуйте перенаправить.

const functions = require('firebase-functions');
const express = require('express');
const request = require('request');
var express_app = express();
express_app.use(body_parser.text({type: ()=>true}));
express_app.all('*', (req, res) => {
    var url = req.path;
    request({
        uri: uri,
        followRedirect: true
      },
      function(err, httpResponse) {
        if (err) {
          return console.error(err);
        }
        res.send(httpResponse.headers.location || uri);
      }
    );
});
exports.url = functions.https.onRequest(express_app);

Также хорошая практика npm install с --save, чтобы они оказались в packages.json. Хотя firebase копирует вашу папку node_modules, большинство других платформ SaaS запускаются npm install.