> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Truy cập thủ công

<Warning>Đây là tài liệu Inertia.js v1, phiên bản không còn được duy trì tích cực. Vui lòng tham khảo [tài liệu v3](/v3/getting-started/index).</Warning>

Ngoài việc [tạo liên kết](/v1/the-basics/links), bạn cũng có thể chủ động thực hiện các lần truy cập / request Inertia bằng JavaScript. Việc này được thực hiện qua phương thức `router.visit()`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit(url, {
      method: 'get',
      data: {},
      replace: false,
      preserveState: false,
      preserveScroll: false,
      only: [],
      headers: {},
      errorBag: null,
      forceFormData: false,
      onCancelToken: cancelToken => {},
      onCancel: () => {},
      onBefore: visit => {},
      onStart: visit => {},
      onProgress: progress => {},
      onSuccess: page => {},
      onError: errors => {},
      onFinish: visit => {},
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit(url, {
      method: 'get',
      data: {},
      replace: false,
      preserveState: false,
      preserveScroll: false,
      only: [],
      headers: {},
      errorBag: null,
      forceFormData: false,
      onCancelToken: cancelToken => {},
      onCancel: () => {},
      onBefore: visit => {},
      onStart: visit => {},
      onProgress: progress => {},
      onSuccess: page => {},
      onError: errors => {},
      onFinish: visit => {},
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit(url, {
      method: 'get',
      data: {},
      replace: false,
      preserveState: false,
      preserveScroll: false,
      only: [],
      headers: {},
      errorBag: null,
      forceFormData: false,
      onCancelToken: cancelToken => {},
      onCancel: () => {},
      onBefore: visit => {},
      onStart: visit => {},
      onProgress: progress => {},
      onSuccess: page => {},
      onError: errors => {},
      onFinish: visit => {},
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit(url, {
      method: 'get',
      data: {},
      replace: false,
      preserveState: false,
      preserveScroll: false,
      only: [],
      headers: {},
      errorBag: null,
      forceFormData: false,
      onCancelToken: cancelToken => {},
      onCancel: () => {},
      onBefore: visit => {},
      onStart: visit => {},
      onProgress: progress => {},
      onSuccess: page => {},
      onError: errors => {},
      onFinish: visit => {},
  })
  ```
</CodeGroup>

Tuy nhiên, nhìn chung sẽ thuận tiện hơn khi sử dụng một trong các phương thức request rút gọn của Inertia. Những phương thức này hỗ trợ đầy đủ các tùy chọn giống `router.visit()`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.get(url, data, options)
  router.post(url, data, options)
  router.put(url, data, options)
  router.patch(url, data, options)
  router.delete(url, options)
  router.reload(options) // Uses the current URL
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.get(url, data, options)
  router.post(url, data, options)
  router.put(url, data, options)
  router.patch(url, data, options)
  router.delete(url, options)
  router.reload(options) // Uses the current URL
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.get(url, data, options)
  router.post(url, data, options)
  router.put(url, data, options)
  router.patch(url, data, options)
  router.delete(url, options)
  router.reload(options) // Uses the current URL
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.get(url, data, options)
  router.post(url, data, options)
  router.put(url, data, options)
  router.patch(url, data, options)
  router.delete(url, options)
  router.reload(options) // Uses the current URL
  ```
</CodeGroup>

Phương thức `reload()` là cách viết tắt tiện lợi, tự động truy cập lại trang hiện tại với cả `preserveState` và `preserveScroll` đều được đặt thành `true`, vì vậy rất phù hợp khi bạn chỉ muốn tải lại dữ liệu của trang hiện tại.

## Phương thức

Khi thực hiện truy cập thủ công, bạn có thể dùng tùy chọn `method` để đặt HTTP method của request thành `get`, `post`, `put`, `patch` hoặc `delete`. Method mặc định là `get`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit(url, { method: 'post' })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit(url, { method: 'post' })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit(url, { method: 'post' })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit(url, { method: 'post' })
  ```
</CodeGroup>

Laravel không hỗ trợ tải file trực tiếp qua `put` hoặc `patch`. Thay vào đó, hãy gửi request bằng `post` và kèm field `_method` có giá trị `put` hoặc `patch`. Kỹ thuật này được gọi là [giả lập HTTP method của form](https://laravel.com/docs/8.x/routing#form-method-spoofing).

## Dữ liệu

Bạn có thể dùng tùy chọn `data` để thêm dữ liệu vào request.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit('/users', {
      method: 'post',
      data: {
          name: 'John Doe',
          email: 'john.doe@example.com',
      },
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit('/users', {
      method: 'post',
      data: {
          name: 'John Doe',
          email: 'john.doe@example.com',
      },
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit('/users', {
      method: 'post',
      data: {
          name: 'John Doe',
          email: 'john.doe@example.com',
      },
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit('/users', {
      method: 'post',
      data: {
          name: 'John Doe',
          email: 'john.doe@example.com',
      },
  })
  ```
</CodeGroup>

Để thuận tiện, các phương thức `get()`, `post()`, `put()` và `patch()` đều nhận `data` làm đối số thứ hai.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', {
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', {
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', {
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', {
      name: 'John Doe',
      email: 'john.doe@example.com',
  })
  ```
</CodeGroup>

## Header tùy chỉnh

Tùy chọn `headers` cho phép bạn thêm header tùy chỉnh vào request.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', data, {
      headers: {
          'Custom-Header': 'value',
      },
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', data, {
      headers: {
          'Custom-Header': 'value',
      },
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', data, {
      headers: {
          'Custom-Header': 'value',
      },
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', data, {
      headers: {
          'Custom-Header': 'value',
      },
  })
  ```
</CodeGroup>

Các header mà Inertia sử dụng nội bộ để truyền trạng thái của nó tới máy chủ có độ ưu tiên cao hơn và vì vậy không thể bị ghi đè.

## Tải file lên

Khi thực hiện lần truy cập / request có chứa file, Inertia sẽ tự động chuyển dữ liệu request thành object `FormData`. Nếu muốn request luôn dùng object `FormData`, bạn có thể sử dụng tùy chọn `forceFormData`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/companies', data, {
      forceFormData: true,
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/companies', data, {
      forceFormData: true,
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/companies', data, {
      forceFormData: true,
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/companies', data, {
      forceFormData: true,
  })
  ```
</CodeGroup>

Để biết thêm thông tin về tải file lên, hãy xem tài liệu chuyên biệt về [tải file](/v1/the-basics/file-uploads).

## Lịch sử trình duyệt

Khi thực hiện các lần truy cập, Inertia tự động thêm một entry mới vào lịch sử trình duyệt. Tuy nhiên, bạn cũng có thể thay thế entry lịch sử hiện tại bằng cách đặt tùy chọn `replace` thành `true`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.get('/users', { search: 'John' }, { replace: true })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.get('/users', { search: 'John' }, { replace: true })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.get('/users', { search: 'John' }, { replace: true })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.get('/users', { search: 'John' }, { replace: true })
  ```
</CodeGroup>

Các lần truy cập đến cùng một URL sẽ tự động đặt `replace` thành `true`.

## Giữ lại state

Mặc định, các lần truy cập lại cùng một trang sẽ tạo một instance page component mới. Điều này khiến các state cục bộ như input của form, vị trí cuộn và trạng thái focus bị mất.

Tuy nhiên, trong một số tình huống, cần giữ lại state của page component. Ví dụ, khi submit form, bạn cần giữ dữ liệu form nếu validation form thất bại ở phía máy chủ.

Vì lý do này, các phương thức `post`, `put`, `patch`, `delete` và `reload` đều đặt tùy chọn `preserveState` thành `true` theo mặc định.

Bạn có thể yêu cầu Inertia giữ state của component khi sử dụng phương thức `get` bằng cách đặt tùy chọn `preserveState` thành `true`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.get('/users', { search: 'John' }, { preserveState: true })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.get('/users', { search: 'John' }, { preserveState: true })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.get('/users', { search: 'John' }, { preserveState: true })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.get('/users', { search: 'John' }, { preserveState: true })
  ```
</CodeGroup>

Nếu chỉ muốn giữ state khi response có chứa lỗi validation, hãy đặt tùy chọn `preserveState` thành "errors".

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.get('/users', { search: 'John' }, { preserveState: 'errors' })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.get('/users', { search: 'John' }, { preserveState: 'errors' })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.get('/users', { search: 'John' }, { preserveState: 'errors' })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.get('/users', { search: 'John' }, { preserveState: 'errors' })
  ```
</CodeGroup>

Bạn cũng có thể đánh giá trì hoãn tùy chọn `preserveState` dựa trên response bằng cách cung cấp một callback.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', data, {
      preserveState: (page) => page.props.someProp === 'value',
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', data, {
      preserveState: (page) => page.props.someProp === 'value',
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', data, {
      preserveState: (page) => page.props.someProp === 'value',
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', data, {
      preserveState: (page) => page.props.someProp === 'value',
  })
  ```
</CodeGroup>

## Giữ vị trí cuộn

Khi điều hướng giữa các trang, Inertia mô phỏng hành vi mặc định của trình duyệt bằng cách tự động đưa vị trí cuộn của body tài liệu (cũng như mọi [vùng cuộn](/scroll-management#scroll-regions) bạn đã định nghĩa) trở lại đầu trang.

Bạn có thể tắt hành vi này bằng cách đặt tùy chọn `preserveScroll` thành `false`.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit(url, { preserveScroll: false })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit(url, { preserveScroll: false })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit(url, { preserveScroll: false })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit(url, { preserveScroll: false })
  ```
</CodeGroup>

Nếu chỉ muốn giữ vị trí cuộn khi response có lỗi validation, hãy đặt tùy chọn `preserveScroll` thành "errors".

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit(url, { preserveScroll: 'errors' })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit(url, { preserveScroll: 'errors' })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit(url, { preserveScroll: 'errors' })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit(url, { preserveScroll: 'errors' })
  ```
</CodeGroup>

Bạn cũng có thể đánh giá trì hoãn tùy chọn `preserveScroll` dựa trên response bằng cách cung cấp một callback.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', data, {
      preserveScroll: (page) => page.props.someProp === 'value',
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', data, {
      preserveScroll: (page) => page.props.someProp === 'value',
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', data, {
      preserveScroll: (page) => page.props.someProp === 'value',
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', data, {
      preserveScroll: (page) => page.props.someProp === 'value',
  })
  ```
</CodeGroup>

Để biết thêm thông tin về tính năng này, hãy xem tài liệu [quản lý cuộn](/v1/advanced/scroll-management).

## Tải lại một phần

Tùy chọn `only` cho phép bạn chỉ yêu cầu một tập con props (dữ liệu) từ máy chủ trong các lần truy cập tiếp theo đến cùng một trang, qua đó giúp ứng dụng hiệu quả hơn vì không cần truy xuất dữ liệu mà trang không có nhu cầu làm mới.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.visit('/users', { search: 'John' }, { only: ['users'] })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.visit('/users', { search: 'John' }, { only: ['users'] })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.visit('/users', { search: 'John' }, { only: ['users'] })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.visit('/users', { search: 'John' }, { only: ['users'] })
  ```
</CodeGroup>

Để biết thêm thông tin về tính năng này, hãy xem tài liệu [tải lại một phần](/v1/advanced/partial-reloads).

## Hủy lần truy cập

Bạn có thể hủy một lần truy cập bằng cancel token mà Inertia tự động tạo và cung cấp thông qua callback `onCancelToken()` trước khi thực hiện truy cập.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', data, {
      onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  })

  // Cancel the visit...
  this.cancelToken.cancel()
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', data, {
      onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  })

  // Cancel the visit...
  this.cancelToken.cancel()
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', data, {
      onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  })

  // Cancel the visit...
  this.cancelToken.cancel()
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', data, {
      onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  })

  // Cancel the visit...
  this.cancelToken.cancel()
  ```
</CodeGroup>

Các callback sự kiện `onCancel()` và `onFinish()` sẽ được thực thi khi một lần truy cập bị hủy.

## Callback sự kiện

Ngoài [sự kiện toàn cục](/v1/advanced/events) của Inertia, Inertia còn cung cấp một số callback sự kiện dành riêng cho từng lần truy cập.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post('/users', data, {
      onBefore: (visit) => {},
      onStart: (visit) => {},
      onProgress: (progress) => {},
      onSuccess: (page) => {},
      onError: (errors) => {},
      onCancel: () => {},
      onFinish: visit => {},
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post('/users', data, {
      onBefore: (visit) => {},
      onStart: (visit) => {},
      onProgress: (progress) => {},
      onSuccess: (page) => {},
      onError: (errors) => {},
      onCancel: () => {},
      onFinish: visit => {},
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post('/users', data, {
      onBefore: (visit) => {},
      onStart: (visit) => {},
      onProgress: (progress) => {},
      onSuccess: (page) => {},
      onError: (errors) => {},
      onCancel: () => {},
      onFinish: visit => {},
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post('/users', data, {
      onBefore: (visit) => {},
      onStart: (visit) => {},
      onProgress: (progress) => {},
      onSuccess: (page) => {},
      onError: (errors) => {},
      onCancel: () => {},
      onFinish: visit => {},
  })
  ```
</CodeGroup>

Trả về `false` từ callback `onBefore()` sẽ khiến lần truy cập bị hủy.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.delete(`/users/${user.id}\
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.delete(`/users/${user.id}\
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.delete(`/users/${user.id}\
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.delete(`/users/${user.id}\
  ```
</CodeGroup>

Bạn cũng có thể trả về promise từ các callback `onSuccess()` và `onError()`. Khi làm vậy, sự kiện "finish" sẽ được trì hoãn cho đến khi promise được resolve.

<CodeGroup>
  ```js Vue 2 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue2'

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.doThing(),
              this.doAnotherThing()
          ])
      }
      onFinish: visit => {
          // This won't be called until doThing()
          // and doAnotherThing() have finished.
      },
  })
  ```

  ```js Vue 3 icon="vuejs" theme={null}
  import { router } from '@inertiajs/vue3'

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.doThing(),
              this.doAnotherThing()
          ])
      }
      onFinish: visit => {
          // This won't be called until doThing()
          // and doAnotherThing() have finished.
      },
  })
  ```

  ```js React icon="react" theme={null}
  import { router } from '@inertiajs/react'

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.doThing(),
              this.doAnotherThing()
          ])
      }
      onFinish: visit => {
          // This won't be called until doThing()
          // and doAnotherThing() have finished.
      },
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.doThing(),
              this.doAnotherThing()
          ])
      }
      onFinish: visit => {
          // This won't be called until doThing()
          // and doAnotherThing() have finished.
      },
  })
  ```
</CodeGroup>

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v1 chính thức](https://inertiajs.com/docs/v1/the-basics/manual-visits). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
