Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 处理资源URI中特殊字符的正确方法是什么?如何妥善逃生?_Javascript_Angularjs_Rest_Spring Mvc_Escaping - Fatal编程技术网

Javascript 处理资源URI中特殊字符的正确方法是什么?如何妥善逃生?

Javascript 处理资源URI中特殊字符的正确方法是什么?如何妥善逃生?,javascript,angularjs,rest,spring-mvc,escaping,Javascript,Angularjs,Rest,Spring Mvc,Escaping,我们的应用程序通过AJAXGET请求实现API来访问实体细节——它曾经被使用过POST,但我们决定改变我们的标准 不幸的是,我们最近遇到了一个设计缺陷 假设我们的API是http://localhost/app/module/entity/detail/{id}其中{id}是与该实体的主键匹配的Spring@PathVariable 如果主键是数字代理键(自动递增),则没有问题。但我们认为这一切都可以通过String主键来实现 碰巧我们发现一些有效的生产数据包含斜杠、反斜杠和主键的分号。我们的表

我们的应用程序通过AJAX
GET
请求实现API来访问实体细节——它曾经被使用过
POST
,但我们决定改变我们的标准

不幸的是,我们最近遇到了一个设计缺陷

假设我们的API是
http://localhost/app/module/entity/detail/{id}
其中
{id}
是与该实体的主键匹配的Spring
@PathVariable

如果主键是数字代理键(自动递增),则没有问题。但我们认为这一切都可以通过
String
主键来实现

碰巧我们发现一些有效的生产数据包含斜杠、反斜杠和主键的分号。我们的表无法使用自动增量代理键,因为它们的大小太大了

更一般地说,我们发现我们没有准备好处理非字母数字字符

缺陷代码最初是什么 下面是我们的应用程序如何在实体列表的单个页面中显示实体数据:

  • 用户导航
    table.jsp
    ,通过POST检索AJAX列表
  • 角度表达式通过
    detail?entityId={{{::row:idAttribute}}

  • 一个有效的链接是由角度链接生成的
  • 示例:

    detail?entityId=5903475934 //numeric case, we have several details page with same navigation pattern
    detail?entityID=AAABBBCCC
    detail?entityID=DO0000099101\test
    
  • 用户单击链接,浏览器指向相应的地址

    \测试//可能会被转义。。。。请稍后阅读更多

  • 页面需要参数中的ID代码来发出正确的AJAX调用

  • 需要从查询字符串中检索实体ID。角度控制器位于一个单独的文件中,该文件看不到查询字符串(并且动态包含,具有相同的页面名称)

  • 发出Ajax调用

    //URL不正确

  • Spring MVC解码
    @PathVariable

  • 不幸的是,该参数被视为
    DO0000099101est

    我们试图解决的问题 我们试图通过避开
    \t
    来修复这个错误,因为它在HTML内容中的存在显然构成了一个bug。Javascript将其解释为一个选项卡

  • 正在尝试URL转义ID
  • 我们试图手动导航到
    http://localhost/blablabla/detail?entityId=DO0000099101%5Ctest
    通过将反斜杠转义到其URL实体。其目的是,如果这起作用,我们可以修改表格页面中的角度代码

    结果是
    \t
    再次出现,与Javascript片段中的一样。从这一点来看,顺序是相同的

    <script type="text/javascript">
        var ____entityId = 'DO0000099101\test';
    </script>
    
  • 尝试使用转义URL手动执行Ajax调用
  • 所以要知道REST的url是
    http://localhost/app/module/entity/detail/{id}
    ,让我们试着看看Spring希望如何转义反斜杠

    http://localhost/app/module/entity/detail/DO0000099101%5Ctest //results in 400 error
    
    http://localhost/app/module/entity/detail/DO0000099101\\test //Chrome reversed the backslash into a forward slash and the result is 404 as expected for http://localhost/app/module/entity/detail/DO0000099101//test
    
  • 使用编码器组件
  • 我们已经试过了(但我在最初的帖子中没有提到)。对于@Thomas comment,我们再次尝试通过控制器本身中的Javascript转义对主键进行编码

        $http.get($const.urlController+'detail/'+encodeURIComponent($scope.entityId))
    
    这种方法的问题是URL中的
    反斜杠-T
    序列被编码为
    %09
    ,这导致服务器端的
    选项卡被解码

  • 使用encodeURIComponent和Java转义
  • 现在我们尝试使用方法4和将硬编码的Java转义(即
    \\t
    )修复到Javascript中进行测试

    <script type="text/javascript">
        var ____entityId = 'DO0000099101\\test';
    </script>
    
    $http.get($const.urlController+'detail/'+encodeURIComponent($scope.entityId))
    
    质询时间 我想用两种方式问这个问题,一种是具体的,另一种是一般性的

  • 具体:如何正确设置
    @PathVariable
    的格式,使其能够保留特殊字符
  • 常规:在其他情况下,在处理可能包含特殊字符的资源ID时需要注意什么
  • 关于第二点,让我更清楚一点。如果您控制REST应用程序和ID的生成,则可以选择只允许字母数字标识符(用户生成的或随机的或任何形式的)和睡眠

    但在我们的例子中,我们需要浏览来自外部系统的实体,这些系统对实体主标识符所允许的字符集有更广泛的限制。
    同样,我们不能使用自动增量代理键。

    控制器:
    $const.urlController+'detail/'+encodeURIComponent($scope.entityId)
    模板:我首先用结果扩展了我的问题,然后我将阅读链接文章如何将
    entityId
    实际注入JS。如果
    \t
    不应该是选项卡,则您的字符串是错误的。我不知道JSP,但我假设您正在执行类似于
    snippet='var\uuuuuuuuuuEntityId=“'+entityId+”;'
    并将该片段插入到标记中?然后您应该将其更改为Java等效的
    snippet='var\uuuuuuuu entityId='+JSON.stringify(entityId)+';'
    结合
    encodeURIComponent()
    应该可以解决您的问题
    http://localhost/blablabla/detail?entityId=DO0000099101%5C%5Ctest
    
    <script type="text/javascript">
        var ____entityId = 'DO0000099101\\test'; //Looks great
    </script>
    
    http://localhost/blablabla/detail/DO0000099101/test
    
    http://localhost/app/module/entity/detail/DO0000099101%5Ctest //results in 400 error
    
    http://localhost/app/module/entity/detail/DO0000099101\\test //Chrome reversed the backslash into a forward slash and the result is 404 as expected for http://localhost/app/module/entity/detail/DO0000099101//test
    
        $http.get($const.urlController+'detail/'+encodeURIComponent($scope.entityId))
    
    <script type="text/javascript">
        var ____entityId = 'DO0000099101\\test';
    </script>
    
    $http.get($const.urlController+'detail/'+encodeURIComponent($scope.entityId))
    
    http://localhost/app/module/entity/detail/DO0000099101%5Ctest //results in 400 error