Angular Router URL-кодирование специальных символов и поведение браузера

Я просто не могу найти решение для такой проблемы. Я разрабатываю поисковую систему, и я хотел бы отображать в URL-адресе то, что пользователь пытается найти, например:

https://my-site.com/search;query=%28rockstar;search=true;page=0

Пользователь пытается найти (rockstar фразу.

Когда я вставляю этот URL-адрес в браузер, он работает, как и ожидалось, но браузер Chrome отображает этот URL-адрес следующим образом:

https://my-site.com/search;query=(rockstar;search=true;page=0

Таким образом, %28 меняется на (. Я не знаю, зависит ли это поведение от Angular или от браузера. Когда у меня есть URL-адрес с (, обновление F5 не работает, потому что Angular Router сообщает о такой проблеме:

Cannot match any routes. URL Segment: 'rockstar;search=true;page=0'

Копирование ссылки из адресной строки URL-адреса также бесполезно, потому что скопированная ссылка содержит символ ( (не %28). Как предотвратить декодирование %28 и других специальных символов браузером в адресной строке URL? Проблема возникает в Angular v5.2.5

Вот демонстрация этой проблемы: https://angular-url-problem.stackblitz.io

Обратите внимание, что в Angular 6 этой проблемы не существует: https://angular-url-problem-v6.stackblitz.io


person Marcin Kapusta    schedule 30.08.2018    source источник
comment
Можете ли вы создать StackBlitz с минимальным кодом, чтобы воспроизвести проблему, пожалуйста?   -  person user184994    schedule 30.08.2018
comment
Если никто не знает ответа на этот вопрос, я постараюсь его дать.   -  person Marcin Kapusta    schedule 30.08.2018
comment
@MarcinKapusta Как спросить указывает иначе: Help others reproduce the problem. Пожалуйста, предоставьте минимальный воспроизводимый пример, чтобы мы могли протестировать его без необходимости реализовывать его самостоятельно (и я настаиваю на Verifiable , что означает, что вы должны воспроизвести проблему, а не просто предоставить stackblitz)   -  person    schedule 30.08.2018
comment
Я спрашиваю, потому что не могу воспроизвести вашу проблему. Если я загружу angular-hzu1wi.stackblitz.io/ работает нормально.   -  person user184994    schedule 30.08.2018
comment
Вы не можете воспроизвести, потому что вы используете параметры запроса после символа ?.   -  person Marcin Kapusta    schedule 30.08.2018
comment
@trichetriche — демо для Angular 5 здесь: angular-url-problem.stackblitz.io и для Angular 6: angular-url-problem-v6.stackblitz.io   -  person Marcin Kapusta    schedule 30.08.2018
comment
Обычно нужно размещать ссылку на код, а не на демо... Но я знаю, как до него добраться. Я смотрю на это.   -  person    schedule 30.08.2018
comment
@MarcinKapusta, у меня такая же проблема. ты решил это?   -  person Rafique Mohammed    schedule 18.10.2018
comment
В некотором роде да. Я решил переписать приложение и не использовать параметры, специфичные для маршрута, а использовать queryParams.   -  person Marcin Kapusta    schedule 18.10.2018


Ответы (1)


Это не работает, потому что вы не смотрите на правильные параметры. В этот stackblitz, как видите, вам даже не нужно кодировать свои параметры.

Вам также не нужно заходить слишком далеко, чтобы создать параметры запроса. Angular обеспечивает высокий уровень абстракции, используйте его в своих интересах.

ngOnInit(): void {
  this._route.queryParamMap
    .subscribe(params => {
      this.form.patchValue({
        query: params.get('query') || '',
      });
    });
}

public onSubmit(): void {
  const query: string = this.form.value.query;
  this._router.navigate(['/search'], {
    queryParams: {
      query
    }
  })
}

EDIT с матричным обозначением: stackblitz

ngOnInit(): void {
  this._route.params
    .subscribe(params => {
      this.form.patchValue({
        query: params['query'] || '',
      });
    });
}

public onSubmit(): void {
  const query: string = this.form.value.query;
  this._router.navigate(['/search', { query }]);
}
person Community    schedule 30.08.2018
comment
Но это не то, чего я ожидаю. Вы предоставляете мне решение, которое добавляет параметры запроса (после символа ?). Это совсем другое решение. - person Marcin Kapusta; 30.08.2018
comment
С матричной записью если хотите. Мои баллы остаются в силе. - person ; 30.08.2018
comment
Это решение Angular 6, и мне нужно решение Angular 5. Я написал, что в Angular 6 все работает. Взгляните на описание вопроса, потому что я его обновил. - person Marcin Kapusta; 30.08.2018
comment
Тогда это проблема, и вам нужно перейти на Angular 6 (извините, я не прочитал ваш вопрос снова, мой плохой). - person ; 30.08.2018
comment
В настоящее время я не могу обновиться до Angular 6, поэтому и спрашиваю :) - person Marcin Kapusta; 30.08.2018
comment
Тогда в настоящее время вы не можете использовать матричную нотацию... Рассмотрите возможность переключения на параметры запроса, которые работают, или попробуйте перейти на 6-ю версию. - person ; 30.08.2018
comment
Спасибо. Я поэкспериментирую с методами router.urlSerializer.serialize и parse, поищу различия в реализации между v5 и v6 angular на github и предоставлю собственное решение. Невозможно изменить URL, потому что нам нужна обратная совместимость с маршрутами :) - person Marcin Kapusta; 30.08.2018
comment
Возможно, вы могли бы также напрямую изменить местоположение с помощью window.location.href и добавить параметры самостоятельно. Недостаток в том, что приложение будет перезагружено, но это еще одно решение среди других ... - person ; 30.08.2018
comment
@trichetriche я использую Angular 6, и я получаю эту ошибку. так что обновление не решает. Эта проблема возникает, когда URL-адрес выглядит примерно так: localhost:8080/tags/raspberry(cake) - person Rafique Mohammed; 18.10.2018
comment
@Rafique только потому, что вы используете Angular 6, не означает, что он должен работать на месте. Вы могли сделать что-то не так и не заметить этого. Не стесняйтесь задавать вопросы по вашей проблеме и приводить минимально воспроизводимый пример. - person ; 18.10.2018