‘#’ 뒤의 fragment가 서버로 전송되지 않아 Permalink 리다이렉트 문제 발생

수정: 아래 답변 덕분에 문제를 파악하여 제목을 그에 맞게 변경했습니다

마이그레이션 작업 중 영구 링크(permalinks)에서 이상한 동작이 발생하고 있습니다.

제 문제는 내부 링크가 리다이렉트되지 않는 문제가 아닙니다. 브라우저 주소창에 URL을 직접 붙여넣어 테스트하고 있을 뿐입니다.

테스트에서 발생해야 하는 두 가지 리다이렉트는 다음과 같습니다:

이것은 게시물(post) 리다이렉트로, 다음과 같이 두 번째 게시물로 리다이렉트되어야 합니다:

이것은 토픽(topic) 리다이렉트로, 다음 주소로 이동해야 합니다:

제 정규화(normalization)가 정상적으로 작동하고 있다는 것은 알고 있습니다. 제 정규식(regexp)은 다음과 같습니다:

/(?:.*)(\/)(?<topicid>\d*.)-(.[^\/#\?]*)(?<parm>\?(\w*)[=](?<start>\d+))?(?:\/)?(\D+(\/)?)?(?<postid>\d+)?(?:\/)?/normalized.\k<topicid>.\k<postid>

그리고 rails 콘솔에서 확인했습니다:

irb(main):069:0> Permalink.normalize_url('https://community.suitecrm.com/languages/17978-why-two-italian-language-packs#16249')
=> "normalized.17978.16249"

irb(main):068:0> Permalink.normalize_url('https://community.suitecrm.com/languages/17978-why-two-italian-language-packs')
=> "normalized.17978."

제가 의도한 결과입니다. Permalinks 테이블에는 다음과 같은 데이터가 있습니다:

데이터베이스에서 보이는 모습은 다음과 같습니다:

하지만 브라우저 URL에 이 주소를 입력하면

다음 주소로 리다이렉트됩니다:

원래 있어야 할 주소인

이 아닙니다.

그래서 첫 번째 게시물이 표시되고, 두 번째 게시물로 스크롤되지 않습니다.

제 정규화 과정에서 제거되었는데 왜 그 #16249 해시(hash)가 다시 추가되는 걸까요?

이 불일치를 드러내는 또 다른 방법(조금 인위적이긴 하지만)은 브라우저 주소창에서 다음 리다이렉트를 시도해 보는 것입니다:

https://community.suitecrm.com/normalized.17978.
정상적으로 다음으로 리다이렉트됩니다:
Reports disappeared - 💬 General Discussion - SuiteCRM

그리고 Why two Italian language packs? - #2 by roberto - Translation and Language Packs - SuiteCRM
정상적으로 다음으로 리다이렉트됩니다:
Reports disappeared - #2 by erevodifosin - 💬 General Discussion - SuiteCRM

그런데 왜 정상적인 프로세스를 거칠 때는 작동하지 않는 걸까요?

영구 링크(Permalinks)는 수신 링크에만 적용되며, 설명문에 그렇게 명시되어 있습니다.

내부 링크를 수정해야 합니다.

글의 초반부에 언급했듯이, 이는 사실이 아닙니다. 저는 제 포럼에서 링크를 클릭하지 않습니다.

하지만 여기서 말하는 "내부 링크"가 무엇을 의미하는지 정확히 이해하지 못할 수도 있습니다. 좀 더 자세히 설명해 주시겠어요? 브라우저 주소창에 URL을 붙여넣는 것이 어떻게 내부 링크가 될 수 있나요?

URL 조각 식별자(# 및 그 이후의 부분)는 브라우저가 서버에 절대 전송하지 않으므로, 리다이렉트의 일부로 사용할 수 없습니다.

그렇게 말씀하시니 이해가 되네요… 하지만 좀 우울하네요.

제 구럼 포럼은 포스트 단위로 리다이렉트할 때 #를 사용하니까, 제대로 된 포스트 단위 리다이렉트는 완전히 불가능한 것 같습니다 :sob:

마이그레이션 과정에서 이런 제한을 겪는 경우가 흔한가요? 이건 Kunena 소프트웨어인데, 꽤 널리 쓰이는 것 같고 다른 곳들도 포스트 링크에 해시를 사용하는 것 같습니다…

이 문제를 계속 머릿속으로 되짚어 보고 있습니다. 정말 짜증나는 제한 사항이네요. 아마도 근본적인 실수는 Kunena 포럼 설계자들이 게시물 링크를 표시할 때 단순히 조각(fragment)만 사용하면서 오래전에 저질러진 것 같습니다… 한숨.

Discourse가 이 문제를 우회할 수 있는 3가지 접근법을 보고 있습니다. (여기서부터는 명백히 바람직한 생각에 빠져드는 영역이라, 이 여정을 즐기시길 바랍니다.)

  1. 페이지가 로드될 때 JavaScript가 작동하여 URI에 해시 조각이 있음을 인식하고, 이를 이용해 서버를 호출하여 올바른 위치로 다시 리다이렉트합니다. 작동은 하지만 이중 리다이렉트가 발생하며, 사용자는 페이지가 다시 로드되는 것을 보게 됩니다.

  2. Discourse가 서버 측에서 각 게시물의 HTML에 이전으로 가져온 post_id를 id 태그로 추가할 수 있습니다. 이렇게 하면 브라우저가 이전 해시 ID를 전달하고, 리다이렉트된 페이지에서 이를 사용해 맨 아래로 스크롤할 수 있습니다. 주요 단점: 사용자가 스크롤할 때만 게시물이 로드되는 Discourse의 고급 스크롤 기능은 이 방식이 충분하지 않다는 점을 의미합니다.

  3. 위의 방법 혼합: Discourse가 서버 측에서 이전 가져온 post_id와 새로운 post_number 간의 대응 테이블을 구성하고, 페이지가 로드될 때 클라이언트에 전송합니다. 클라이언트의 JavaScript는 URI에 해시가 있음을 인식하고, 해당 테이블을 이용해 그 해시를 변환한 후, 자체 스크롤 기능을 사용하여 올바른 게시물까지 내려갑니다.

이것을 구현하려면 많은 노력이 필요하고 성능 저하라는 페널티가 따릅니다. 하지만 완벽이전을 가능하게 할 수는 있겠죠…

이것들은 완전한 해결책이 아닙니다. 사용자가 이미 Discourse에 로그인되어 있지 않으면 리디렉션이 여전히 작동하지 않기 때문입니다. 외부 링크를 통해 그렇게 도착할 가능성은 훨씬 낮습니다.

현재 내부/외부 리다이렉트에 대해 취하고 있는 접근 방식은 다음과 같습니다:

기존 사이트는 https://suitecrm.com/suitecrm/forum/에, 새 사이트는 https://community.suitecrm.com/에 있습니다.

마이그레이션된 서버가 라이브로 전환되면, 기존 사이트에서 새 사이트로 게이트웨이 리다이렉트를 수행합니다.

내부 링크는 https://suitecrm.com/suitecrm/forum/로 시작하도록 그대로 유지합니다. 사용자가 이 링크를 클릭하면 실질적으로는 외부 링크로 취급됩니다. 하지만 그 후 게이트웨이 리다이렉트가 발생하여 다시 Discourse로 들어오게 되고, 이때 영구 링크(퍼malink)가 정상적으로 작동해야 합니다.

맞습니까? 아직 이 방식을 시도해 보지 않았지만… 동일한 도메인 이름과 폴더를 사용하려 한다면 불가능할 것 같지만, 우리는 그렇게 하지 않습니다.

해야 할 일은 퍼malink 리디렉트를 사용하는 것입니다.

저는 /oldpost/POST_ID와 같은 permalink를 만들고, /forum./category/someslug#1234를 그 링크로 리디렉트하도록 permalink 리디렉트를 작성하는 경우가 많습니다.

"영구 링크 리디렉션"이라고 할 때, 사이트 설정인 permalink normalizations를 말씀하시는 건가요?

아! 맞아요. 죄송해요. 제 뇌가 아직 늦은 시간이라 좀 멍했던 것 같아요.

알겠습니다 :slight_smile:

하지만 저는 Permalink 정규화를 사용하고 있습니다(제 첫 번째 게시물을 참고하세요). 해시 부분은 서버에 절대 전송되지 않으므로, 클라이언트 측 JavaScript가 마법을 부리는 것이 아니라면, 포스트 수준 링크에 해시만 사용하는 포럼은 Discourse(또는 다른 어떤 소프트웨어)로 마이그레이션할 때 리다이렉트 측면에서 적절하게 마이그레이션될 수 있는 방법이 전혀 없습니다.

죄송합니다. 그 부분을 충분히 주의 깊게 읽지 않았습니다. 해시 이후의 요소를 이전에 사용했던 것 같았지만, 아마도 그렇지 않은 것 같습니다. 최근 해당 해시 포스트 ID가 있었던 사례를 기억하지만, 아마도 클라이언트가 토픽 수준의 리다이렉트만 원했던 것 같습니다. 301 리다이렉트의 경우, 올바른 토픽으로 도달하는 것이 충분히 좋을 것 같습니다.