跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 后端要求前端传的查询参数
未分類
26 4 月 2020

后端要求前端传的查询参数

后端要求前端传的查询参数

資深大佬 : zycojamie 92

比如,你输入一个手机号,进行查询,要把你手机号的值,查询是 like 还是=,数据是 string 还是 int,模糊还是精准查询,全部前端拼给后端。。。

这种方案可行吗。。。

大佬有話說 (77)

  • 資深大佬 : onepunch

    模糊查询前端做

  • 資深大佬 : racecoder00

    不怕前端传个 drop table?

  • 資深大佬 : dremy

    SQL 注入了解一下,公司分分钟倒闭

  • 資深大佬 : opengps

    关键词,和是否 like,可以传
    至于 string 还是 int 啥意思?

  • 資深大佬 : Jooooooooo

    可行

    关注一下防注入就行

    不过虽然是可行, 方案不合理啊, 前端关心的是”模糊查询”而不是”模糊查询用 like”

  • 資深大佬 : hedamao9999

    传一串字符串,如果本身其实是可以精确匹配到的,但是查询人以为是模糊匹配的,因而传的是 like,后端怎么处理呢?一串非常长的数字,本来应该是字符串形式存放的,查询人以为是数字,传的是 int,此时又该怎么处理呢

  • 資深大佬 : jatesun

    算了,这种事前端就别揽了

  • 主 資深大佬 : zycojamie

    [' tempMatchType ": " 5,4 ", " propertyName ": " name,mobile, " propertyvaluel ": ",13541218876 "),
    {" tempMatchType ": " 7 ", " propertyName ": " age " " propertyvaluel ": " 12 ", " tempType ": " Integer "},
    tempMatchType ": " 11 ", " propertyName ": " role.id ", " prepertyvalue1 ": " 1,2,3,4 ", " tempType ": " List < Long >"}]
    翻译成 hql = where ( name like %张三%' or mobile = 13541218876 and age > 12 and role.idin ( 1.2.3.4 )

    前端就要把查询参数封装成上面那种数组

  • 主 資深大佬 : zycojamie

    @jatesun 后端架构师说,为了他们拜托大量 if else,所以要求前端按照他们订的查询规则封装请求参数。。。

  • 資深大佬 : littleylv

    我觉得主的意思并不是说前端要拼接好 ‘mobile like ‘%123%’’这样提交给后端,而是使用
    {‘field’: ‘mobile’, ‘value’: ‘123’, ‘is_fuzzy’: true} 这样传给后端,让后端去拼接。

  • 資深大佬 : loading

    先在手机号前后拼接%,然后参数查询,用 like 。

    如果有注入风险,请大佬们马上提醒我。

  • 資深大佬 : loading

    sql 参数拼接还是不难的,没几行。
    谁都是 crud boy 。

  • 主 資深大佬 : zycojamie

    @littleylv 类似,但要求更复杂些(把大于等于,小于,小于等于,等于)都约定好是什么特定值,然后前端传参的时候,就要传(大于等于,小于,小于等于,等于)

  • 資深大佬 : littleylv

    @loading #11
    @loading #12 没看懂你想表达什么

    @zycojamie #13 我觉得这么做挺好的,没问题

  • 資深大佬 : Rwing

    GraphQL 欢迎你

  • 資深大佬 : yukiloh

    这种接口别被我逮到,不然就直接送你出名

  • 資深大佬 : ZSeptember

    这不是很正常的吗,难道不同的查询就要新增加一个接口?
    RESTful 一般只提供一个查询接口,参考
    https://github.com/Microsoft/api-guidelines/blob/master/Guidelines.md#971-filter-operations

  • 資深大佬 : lancerly

    @zycojamie 这太搞笑了吧,前端的代码就不需要整洁性了?就可以随便写一大堆 if else 了?

  • 資深大佬 : wangxiaoaer

    @yukiloh #16 这种接口有什么问题吗?

    假如一些业务系统就是很需要很精确的查询:比较、类别、模糊 /精确切换等你怎么做???

    现在后端要求是前端把这些非常精细的条件传过去,后端翻译成 sql,又没让前端直接拼、传 sql,只要后端在生成 sql 的时候做好防注入,有什么问题?

  • 資深大佬 : pap3r

    前端爸爸不帮后端儿子擦屁股

  • 資深大佬 : jziwenchen

    graphql 可以了解看看

  • 資深大佬 : sun1991

    要区分具体需求是什么再谈实现, 不要一上来就一顿喷…
    曾经做过的灵活可定制查询界面大概就是这样的实现.

  • 資深大佬 : lneoi

    这样处理太繁琐了吧 有点像是做后台的大量查询的需求

  • 資深大佬 : fumichael

    像这个一样?前端可以组装查询条件呀
    但不能后端直接接收前端参数作为 sql 语句
    我想到的是,可以使用枚举进行处理
    https://i.loli.net/2020/04/17/AfIQ4U7weZtDdSB.png

  • 資深大佬 : purensong

    graphQL 不错

  • 資深大佬 : cedoo22

    没安全规则吗???让前端拼。。

  • 資深大佬 : z1154505909

    前端拼接????头一次听说

  • 資深大佬 : CismonX

    突然想起来之前我们学校有个英语课在线答题系统,前端传给后端的参数是一条条完整的 SQL 。

    有好事者试着传了个 DROP TABLE xxx,然后就没有然后了

  • 主 資深大佬 : zycojamie

    安全的话,后端说他们通过框架层去校验和拦截,前端需要把传统的查询参数由{ user:”张三”}变成{ user:{
    matchType:”1″,
    propertyName:”user”,
    propertyValue:”张三”,
    dataType:”string”
    }}
    matchType 为 1 代表“包含”

  • 資深大佬 : Erroad

    前端把 ui“翻译”成参数还是很正常的,拼 sql 是肯定不行的,让前端拼 sql 给后端的后端都是 xx

  • 資深大佬 : littleylv

    @cedoo22 #26
    @z1154505909 #27
    你们到底有没看仔细看主说的。。。。。。。。。。。。。。无力吐槽

  • 資深大佬 : wyz123723

    现在后端真是越来越烂 /懒了

  • 資深大佬 : wellsc

    graphql + 1

  • 資深大佬 : 1et

    string 和 int 确实有点迷,传 like 、=没什么问题,比如 name:3 默认等值查询,name_like:3 是模糊查询

  • 資深大佬 : javapythongo

    我觉得可以

  • 資深大佬 : buffzty

    我就是这样做的.已经用了一年多了.如果项目很小,开发速度第一可以试试.缺点就是只能普通查询,如果查询有 join 的需要手动写规则
    下面这个是我查询列表的一个通用方法.新加一个模型只需要设置一下 model 类型 和 filter 映射和 order 映射
    用这套接口速度起飞,但有局限性
    “`php
    // Base controller
    public function lists(): Json
    {
    $json = new JsonRes();
    [$page, $limit, $filter, $order, $extra] = $this->getListParam();
    $scene = $extra[‘scene’] ?? $this->model::SCENE[‘default’];
    $where = $this->model::buildWhereMap($filter);
    $fmtOrder = $this->model::buildFmtOrder($order);
    if ( $scene === $this->model::SCENE[‘admin’] && !$this->isAdminUser() ) {
    return $this->noAuth();
    }
    [$list, $count] = $this->model::getListNotThrowEmptyEx($page, $limit,
    $this->model::NEED_COUNT, $where, [], $order);
    $fmtList = [];
    /** @var appmodelBase $model */
    foreach ($list as $model) {
    $fmtList[] = $model->getFmtDetail($scene);
    }
    $json->setData([
    ‘list’ => $fmtList,
    ]);
    $json->setPage($page);
    $json->setLimit($limit);
    $json->setCount($count);
    return json($json);
    }

    // Base Model
    /**
    * 根据 filter 构建查询条件.
    *
    * @param array|null $filterList
    * @param array $filterFieldMapDbField
    * @return array
    */
    public static function buildWhereMap($filterList, array $filterFieldMapDbField =
    []): array
    {

    $filterFieldMapDbField = empty($filterFieldMapDbField) ? static::FILTER_FIELD_MAP_DB_FIELD : $filterFieldMapDbField;
    $map = [];
    if ( !is_array($filterList) ) {
    return [];
    }
    foreach ($filterList as $filterField => $item) {
    if ( $item instanceof Closure ) {
    $map[] = $item;
    continue;
    }
    if ( !is_array($item) || !array_key_exists(‘condition’, $item)
    || !array_key_exists(‘val’, $item) ) {
    continue;
    }
    if ( $item[‘val’] === ” || $item[‘condition’] === Condition::TYPE[‘undefined’] ||
    !in_array($item[‘condition’], Condition::TYPE, true)
    ) {
    continue;
    }
    if ( !array_key_exists($filterField, $filterFieldMapDbField) ) {
    continue;
    }
    $dbField = $filterFieldMapDbField[$filterField];
    $condition = Condition::DB_CONDITION[$item[‘condition’]];
    $map[] = [
    $dbField, $condition, Condition::formatVal($item[‘condition’], $item[‘val’]),
    ];
    }

    return $map;
    }
    “`
    前端代码:
    “`typescript
    // 一个模型只需要定义下面这些 就可以使用通用增删改查 5 个接口了
    type Model = Expert
    const route = ‘/expert’
    type FilterKeys =
    | ‘id’
    | ‘ctime’
    | ‘expertCode’
    | ‘name’
    | ‘userName’
    | ‘departmentId’
    | ‘orgCode’
    | ‘orgName’
    | ‘provCode’
    | ‘cityCode’
    | ‘countyCode’
    | ‘provName’
    | ‘cityName’
    | ‘countyName’
    | ‘level’
    | ‘intro’
    | ‘type’
    | ‘mobile’
    | ‘phone’
    | ’email’
    | ‘qq’
    | ‘wx’
    | ‘remark’
    | ‘serviceType’
    type OrderKeys = ‘id’ | ‘ctime’
    type Scene = ‘admin’ | ‘default’
    interface QueryExtra extends BaseExtra<Scene> {}
    type ActGetListParam = GetListParam<FilterKeys, OrderKeys, QueryExtra>
    type AddData = Omit<Model, ‘adeptLabelList’ | ‘department’ | ‘id’>
    type EditData = AddData & Pick<Model, ‘id’>

    export async function lists<T = Model>(data: ActGetListParam) {
    return bpost<{ list: T[] }>({
    url: route + ‘/list’,
    data,
    })
    }
    “`

  • 資深大佬 : buffzty

    谁能告诉我这破站到底怎么发代码?

  • 資深大佬 : baiyi

    GraphQL +10086

  • 資深大佬 : xgfan

    这不就是那个男人经常推广的场景吗?

  • 資深大佬 : masker

    @pap3r 你这种优越

  • 資深大佬 : vitoliu

    防 sql 注入的工具很多,后端随便引一下就解决了,而且的确能摆脱大量的判空和 if else 。
    参数混淆啥的也都没做,而且看参数名应该是 B 端系统吧,用户量少这么干的确也没啥问题。
    不过前端传驼峰不传下划线的确让我感觉挺不得劲的哈哈哈。

  • 資深大佬 : areless

    可行,写了一套这样的前后端,本来想用。感觉那就每天没事干,盯着前端写 SQL 就可以了

  • 資深大佬 : IGJacklove

    @ZSeptember 感觉一个接口和这个也没啥关系吧,换个方式,加个枚举什么的都比前端传 like 强吧

  • 資深大佬 : Deffi

    我是移动端,要是考虑版本迭代,逻辑变更,我不会用这种接口。前端应该尽量少做逻辑处理

  • 資深大佬 : red2dog

    graphql ++

  • 資深大佬 : guyeu

    在有很多复杂查询的场景使用自己的 DSL 代替若干个接口是有意义的,但需要注意的是不应该让前端拼 SQL,而且需要对 DSL 的应用范围进行限制,最好是从设计上避免危险操作的可能性。

  • 資深大佬 : guyeu

    不拼 SQL 的主要原因是让数据库和客户端解耦,因为在不通的架构模式下 SQL 的写法可能有较大差异,这不应该影响客户端实现,而表结构也不应该对客户端透明。

  • 資深大佬 : k9990009

    可以的,但是不要前端拼 SQL 。以前我们前端人手不够,前端也是后端写的。自定义参数解析。然后后端调用根据关键字,这个关键字正好是 mybatis plus 的方法名,通过反射调用自动拼。后端只要继承默认实现 CRUD 就好了。比如前端传 name_leftlike,只要写前端就好了,超爽。后端做参数过滤就好了。

  • 資深大佬 : oatw

    @zycojamie 不考虑后端的前端和不考虑前端的后端,都是业余选手。就像这个架构师。

  • 資深大佬 : randyo

    流量不要钱吗,前端为了摆脱复杂数据果断抛回去让后端自己写

  • 資深大佬 : rioshikelong121

    这样前端也得懂表结构了 而且复杂的 sql 怎么处理。还得单独写接口吧。

  • 資深大佬 : kohos

    这种如果是 where 后面全部靠前端提供的参数生成的话,很不安全,例如主的接口,改一下 roleId 就能操作其他角色的数据了,后端想偷懒也不是这样做的

  • 資深大佬 : component

    GraphQL 了解一下

  • 資深大佬 : jugelizi

    可行
    但不是拼接。
    应该是传 json k v 指定查询类型 以及查询内容

  • 資深大佬 : MilletChili

    一般的查询,我都是叫前端去拼的,虽然我就是那个前端
    start_num = int(request.GET.get(‘start_num’) or 0) # 起始数
    get_num = int(request.GET.get(‘get_num’) or 10) # 需求数
    filters = request.GET.get(‘filters’) # 筛选条件
    sorts = request.GET.get(‘sorts’) # 排序条件
    want_fileds = request.GET.get(‘want_fileds’) # 指定需要的字段
    is_distinct = request.GET.get(‘is_distinct’) # 是否去重

    qset = model.objects.using(using_database).all()

    if filters:
    # print(‘筛选条件:’,filters)
    qset = filterHelper(filters, qset)
    if sorts:
    # print(‘排序条件:’,sorts)
    qset = qset.order_by(*sorts.split(‘,’))
    if is_distinct == ‘yes’:
    qset = qset.distinct()

    all_num = qset.count() # 总个数
    qset = qset[start_num: start_num + get_num]

    if want_fileds:
    data_list = createSerializers(model, want_fileds.split(‘,’))(qset, many=True).data
    else:
    data_list = Ser_L(qset, many=True).data
    data = {‘all_num’: all_num, ‘data_list’: data_list}

  • 資深大佬 : CEBBCAT

    @buffzty #36 /t/663565

  • 資深大佬 : wushigejiajia01

    主大致意思: 前端传参,要把参数类型,以及查询范围都传给后端,这样后端能把接口做的很灵活多用

    应该是这个意思吧?

    只要不是由前端拼接 SQL,这没啥问题啊

  • 資深大佬 : shadeofgod

    这届后端还是不行

  • 資深大佬 : jswh

    管理后台可以,产品中最好不要。这事我也干过,本质上可所谓的 restful 或者 graphql 的想法是一样的,就是定义一套自己的 DSL 免得老是做相同的事情。

  • 資深大佬 : lizhuoli

    重新自己实现一个垃圾版本 GraphQL ?意义何在

  • 資深大佬 : hooopo

    graphql 了解一下

  • 資深大佬 : puilu

    这届后端不行

  • 資深大佬 : hq136234303

    @zycojamie 你们架构师真的可爱。如果是前端加密做的话 终有一天解开 sql 注入 会爽的飞起的。。。。

  • 資深大佬 : a1562619919

    数据量极小的模糊查询前端做,比如手机登录帐号。但数据多到超过几十个了明显前端不该处理,或者涉及业务的数据尽量不让前端处理,前端可以模糊查询一下个人非业务的缓存数据(个人姓名手机号这种)

  • 資深大佬 : icy37785

    GraphQL + 10086

  • 資深大佬 : bllue

    架构师应该拎得清
    只要避免前端拼接后端拿来直接用的情况

  • 資深大佬 : Jrue0011

    @zycojamie 这种设计感觉和 DSL 有点像,elastic search 的查询 api 就是类似的设计

  • 資深大佬 : yufeng0681

    我能想到 前端能拒绝的理由:
    如果有三个终端 需要使用这个功能。 三个终端的开发都要懂 SQL,都要完整测试,不合理,也浪费成本。

  • 資深大佬 : SyncWorld

    直接传 SQL 岂不是美包包~

  • 資深大佬 : qce7

    我们这边用 Yii2 的 DSL

    // 过滤条件
    // 过滤条件按需使用,没有过滤条件就不传 filter
    “filter”: {
    // and 表示 “且”,也支持 or,但是实际业务用的比较少而且性能不佳 or 不建议使用
    “and”: [
    // like 条件
    {“mobile”: {“like”: “1”}},
    // level = 1
    {“level”: 1},
    // 范围条件 id in [2, 5, 9]
    {“id”: {“in”: [2, 5, 9]}},
    // createdAt > 0
    {“createdAt”: {“gt”:0}},
    // createdAt < 10000000000
    {“createdAt”: {“lt”:10000000000}}
    ]
    }
    // 每页记录数,后端默认 10 条
    “perPage”: 10,
    // 请求页数
    “page”: 1,
    // 排序值,优先级从前到后“-”表示倒序
    “sort”: “-isDefault,-isCertified,-id”
    }

  • 資深大佬 : SjwNo1

    graphql 吧,sql 不安全不太好

  • 資深大佬 : michaelcheng

    复杂的查询传参还是可以的,不一定是要 sql ,语义化的传参,约定参数类型、运算符、值约束等

  • 資深大佬 : a852695

    如果是直接传 sql 不可,但是玩着玩着就变成了直接传 sql,不信试试看?后端尝到了甜头。
    如果是拼约定字符串可以,玩着玩着,自己都不知道约定了啥。

  • 資深大佬 : onfuns

    可行,不过这种方案都是用在内网的系统,可以减少很多的工作量。外网的应用还是应该规规矩矩的,现在的安全可是很敏感了。

  • 資深大佬 : royzxq

    这不就是传说中 apiJSON 的场景吗, 让你们后端用啊(

  • 資深大佬 : pap3r

    @masker 后端儿子连数据类型都要前端传 怎么优越了? 你就是后端儿子吧

  • 資深大佬 : masker

    @pap3r 说实话挺可怜你们这种伪物理阉割的太监的呀。。。自己生育功能不行,还喜欢到处叫别人儿子。。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具