简体   繁体   English

播放框架:从coffeescript传递特殊字符时出现URISyntaxException

[英]Play Framework: URISyntaxException when passing special character from coffeescript

Currently I'm doing a search box in a project with Play Framework. 目前,我正在使用Play Framework在一个项目中执行搜索框。 I made a simple code that pass the search_box value in a "on input" and query the search result from server. 我编写了一个简单的代码,在“输入时”传递search_box值,并从服务器查询搜索结果。

$(".search_box").on "input", (event) ->
LoadResult("/route_to_fetch_result/" + $(".search_box").val())
//LoadResult is a function that fetch json result returned by the search query.

The problem occurs when user inputted any of these special character ('[', ']', '#', '%', '/', '\\' or '|') to the search box. 当用户在搜索框中输入这些特殊字符(“ [”,“]”,“#”,“%”,“ /”,“ \\”或“ |”)中的任何一个时,就会出现问题。 As the function returned internal server error. 由于该函数返回内部服务器错误。

The error persists even after I put a "try-catch" block on the query and the function in the controller that didn't fire. 即使我在查询上放置了“ try-catch”块,并且控制器中的功能没有触发,该错误仍然存​​在。

def getSearch_result(keyword: String) = Action { implicit request =>
    try{
        val searchList = Model.getSearch_result(keyword)
        Ok(Json.toJson(searchList))         
    }
    catch{ case _ => /*do return empty*/ }
}

The query function in the models 模型中的查询功能

def getSearch_result(keyword: String): List[Search_result] = DB.withConnection{ implicit c =>
    try{
        SQL("""query LIKE {keyword}""").on('keyword -> ("%"+keyword+"%")).as(search_resultParser *)
    }
    catch{ case _ => /*do return empty*/ }
}

Directly opening the route with same parameter on the browser returned a URISyntaxException. 在浏览器上直接使用相同参数直接打开路由会返回URISyntaxException。

URISyntaxException: Illegal character in path at index 22: /route_to_fetch_result/1[
java.net.URISyntaxException: Illegal character in path at index 22: /route_to_fetch_result/1[
 java.net.URI$Parser.fail(Unknown Source)
 java.net.URI$Parser.checkChars(Unknown Source)
 java.net.URI$Parser.parseHierarchical(Unknown Source)
 java.net.URI$Parser.parse(Unknown Source)
 java.net.URI.<init>(Unknown Source)
 play.core.server.netty.PlayDefaultUpstreamHandler$$anon$1.path(PlayDefaultUpstreamHandler.scala:98)
 play.docs.DocumentationHandler.maybeHandleDocRequest(DocumentationHandler.scala:58)
 play.docs.DocumentationHandler.maybeHandleDocRequest(DocumentationHandler.scala:28)
 play.core.ReloadableApplication.handleWebCommand(ApplicationProvider.scala:171)
 play.core.server.Server$$anonfun$getHandlerFor$1.apply(Server.scala:79)
 play.core.server.Server$$anonfun$getHandlerFor$1.apply(Server.scala:79)
 scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
 scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:124)
 scala.util.control.Exception$Catch.apply(Exception.scala:102)
 scala.util.control.Exception$Catch.either(Exception.scala:124)
 play.core.server.Server$class.getHandlerFor(Server.scala:79)
 play.core.server.NettyServer.getHandlerFor(NettyServer.scala:35)
 play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$8.apply(PlayDefaultUpstreamHandler.scala:117)
 play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$8.apply(PlayDefaultUpstreamHandler.scala:117)
 scala.util.Either.fold(Either.scala:98)
 play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:111)
 org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
 org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
 org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
 com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62)
 org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88)
 org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
 org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
 org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:108)
 org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
 org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
 org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
 org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
 org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)
 org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)
 org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435)
 org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
 org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
 org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
 org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
 org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
 org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
 org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109)
 org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312)
 org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90)
 org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
 org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
 org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
 java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 java.lang.Thread.run(Unknown Source)

Currently I'm preventing the user to input special characters via a keypress event. 目前,我阻止用户通过按键事件输入特殊字符。 Is there a better solution to this? 有更好的解决方案吗?

The special characters are not valid in a URL. 特殊字符在URL中无效。 You need to encode them: 您需要对它们进行编码:

encodeURIComponent($(".search_box").val())

The same thing will happen if you have a route like this: 如果您有这样的路线,将会发生相同的事情:

GET    /search/:keyword                  controllers.Page.search(keyword: String)

And you manually visit: 您手动访问:

/search/bad[url

Results in: 结果是:

java.net.URISyntaxException: Illegal character in path

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM