从scala-js中的url中提取字段

时间:2016-12-06 05:35:33

标签: scala.js

假设我有一个网址:

https://example.com/myproject/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all

或者它可能是localhost上的网页,如:

localhost:63342/my project/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all

我将从二维数组中的这些网址中提取查询字段(显示在'?'之后),如下所示:

_ijt    |    hsdlgh8h5g8hh489sajoej
a       |    102
b       |    a m
c       |    45
d       |    all
e       |    all

请注意' b'领域,我已经取代了'%20'有空间。这些字段如_ijt,a,b,c,d,e等可以在数量和名称上有所不同,例如' a'可以是城市'。 到目前为止,我已经使用正则表达式来提取出'''然后使用split("&")方法将字符串拆分为多个字符串。 代码 -

val url=localhost:63342/my project/index-dev.html?_ijt=hsdlgh8h5g8hh489sajoej&a=102&b=a%20m&c=45&d=all&e=all
val pattern="""(http|htpps)([A-Za-z0-9\:\/\%\-\.]*)\?""".r
val temp_url=pattern.replaceFirstIn(url,"")
val fields=temp_url.split("&")
println(fields.foreach(println))

,输出为:

_ijt=hsdlgh8h5g8hh489sajoej
a=102
b=a%20m
c=45
d=all
e=all

但它似乎不是正确的方法。有什么帮助吗?

6 个答案:

答案 0 :(得分:3)

使用js.URIUtils.decodeURIComponent准确解码%个编码字符。

答案 1 :(得分:1)

您需要在查询参数值上调用js.URIUtils.decodeURIComponent

val fields=temp_url.split("&").map(js.URIUtils.decodeURIComponent)

decodeURIComponentnative Javascript function,scala.js为a simple interface

或者,您可以使用一些库来解析用Scala编写的URL。解析URL通常会带来安全隐患,并且很容易出错。图书馆通常也支持任何满足相关标准/ RFC的输入。

答案 2 :(得分:1)

令人惊讶的是,很难找到适用于Scala.js和Scala(jvm)的整个库的库。 java.net.URI将为您提供查询字符串,java.net.URLDecoder.decode将删除URL编码,但我还没有看到任何可以获得结构良好的查询片段的东西。它不是火箭科学,但它很常见,你认为你不需要自己写它。

Fastparse将完成这项工作:

  val url = new java.net.URI("http://example.com/?a=1&b%20=b+is+2&c=#someAnchor?a=b")
  println(s"query string is: ${url.getQuery}")

  val individualElements =
    P(CharsWhile {
      case '&' | '=' | '#' => false
      case _ => true
    }.!.map(x => java.net.URLDecoder.decode(x, "UTF-8")))

  val keyValuePair: core.Parser[(String, Option[String]), Char, String] =
    individualElements ~ "=" ~ individualElements.?

  val pairs: core.Parser[Seq[(String, Option[String])], Char, String] =
    keyValuePair.rep(sep = "&")

  val parsed: Parsed[Seq[(String, Option[String])], Char, String] =
    pairs.parse(url.getQuery)

  parsed match {
    case Success(items, _) => println(s"items: ${items.toList}")
    // prints:
    // items: List((a,Some(1)), (b ,Some(b is 2)), (c,None))
  }

答案 3 :(得分:0)

建议使用" decodeURIComponent"和" java.net.URI"我提出了这个快速而肮脏的解决方案,几乎肯定可以改进,但也许有帮助:

def getUrlParameters(url: String): Map[String, Array[String]] = {
    java.net.URI.create(url).getQuery.split('&').map(js.URIUtils.decodeURIComponent).map { p =>
      val split = p.split('=')
      (split.head, split.tail.mkString("="))
    }.groupBy(_._1).map(m => m._1 -> m._2.map(_._2))
}

def getUrlParameter(url: String, parameter: String): Option[String] = {
    getUrlParameters(url).get(parameter).flatMap(_.headOption)
}

答案 4 :(得分:0)

太晚了,但是出于希望,对谷歌来的任何人都没有帮助。让:

def uriParameterExtractor(uri: String): Map[String, String] =
js.URIUtils.decodeURIComponent(uri).tail.split("&").toList.map(x => (x.split("=").head, x.split("=").tail.head)).toMap

然后使用dom.window.location.search参数调用此函数。您可以使用此函数结果的相应键来查询感兴趣的任何参数值,即:

  • uriParameterExtractor(dom.window.location.search)("a")将计算为102

  • uriParameterExtractor(dom.window.location.search)("b")将计算为a m

  • 等等

答案 5 :(得分:-1)

使用以下scala / scalajs库: https://github.com/lemonlabsuk/scala-uri

import io.lemonlabs.uri.Url

val uri = Url.parse("http://example.com/path?a=b&a=c&d=e")
uri.query.paramMap // This is: Map("a" -> Vector("b", "c"), "d" -> Vector("e"))