mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-30 09:27:13 +00:00
refactor(utils, vue-app): use ufo
to parse queries and join urls (#8765)
This commit is contained in:
parent
c8a4b91ad4
commit
119091c8d1
@ -69,7 +69,6 @@ export default () => ({
|
||||
fetch: true,
|
||||
clientOnline: true,
|
||||
clientPrefetch: true,
|
||||
clientUseUrl: false,
|
||||
componentAliases: true,
|
||||
componentClientOnly: true
|
||||
}
|
||||
|
@ -189,7 +189,6 @@ Object {
|
||||
"asyncData": true,
|
||||
"clientOnline": true,
|
||||
"clientPrefetch": true,
|
||||
"clientUseUrl": false,
|
||||
"componentAliases": true,
|
||||
"componentClientOnly": true,
|
||||
"deprecations": true,
|
||||
|
@ -164,7 +164,6 @@ Object {
|
||||
"asyncData": true,
|
||||
"clientOnline": true,
|
||||
"clientPrefetch": true,
|
||||
"clientUseUrl": false,
|
||||
"componentAliases": true,
|
||||
"componentClientOnly": true,
|
||||
"deprecations": true,
|
||||
@ -550,7 +549,6 @@ Object {
|
||||
"asyncData": true,
|
||||
"clientOnline": true,
|
||||
"clientPrefetch": true,
|
||||
"clientUseUrl": false,
|
||||
"componentAliases": true,
|
||||
"componentClientOnly": true,
|
||||
"deprecations": true,
|
||||
|
3
packages/types/config/features.d.ts
vendored
3
packages/types/config/features.d.ts
vendored
@ -2,6 +2,9 @@ export interface NuxtOptionsFeatures {
|
||||
asyncData?: boolean
|
||||
clientOnline?: boolean
|
||||
clientPrefetch?: boolean
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
clientUseUrl?: boolean
|
||||
componentAliases?: boolean
|
||||
componentClientOnly?: boolean
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { joinURL } from 'ufo'
|
||||
|
||||
export const encodeHtml = function encodeHtml (str) {
|
||||
return str.replace(/</g, '<').replace(/>/g, '>')
|
||||
}
|
||||
@ -12,13 +14,7 @@ export const isUrl = function isUrl (url) {
|
||||
return ['http', '//'].some(str => url.startsWith(str))
|
||||
}
|
||||
|
||||
export const urlJoin = function urlJoin () {
|
||||
return [].slice
|
||||
.call(arguments)
|
||||
.join('/')
|
||||
.replace(/\/+/g, '/')
|
||||
.replace(':/', '://')
|
||||
}
|
||||
export const urlJoin = joinURL
|
||||
|
||||
/**
|
||||
* Wraps value in array if it is not already an array
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { stringify } from 'querystring'
|
||||
import Vue from 'vue'
|
||||
import { normalizeURL, joinURL } from 'ufo'
|
||||
import { joinURL, normalizeURL, withQuery } from 'ufo'
|
||||
<% if (fetch.server) { %>import fetch from 'node-fetch'<% } %>
|
||||
<% if (features.middleware) { %>import middleware from './middleware.js'<% } %>
|
||||
import {
|
||||
@ -58,20 +57,19 @@ const createNext = ssrContext => (opts) => {
|
||||
ssrContext.nuxt.serverRendered = false
|
||||
return
|
||||
}
|
||||
opts.query = stringify(opts.query)
|
||||
opts.path = opts.path + (opts.query ? '?' + opts.query : '')
|
||||
let fullPath = withQuery(opts.path, opts.query)
|
||||
const $config = ssrContext.runtimeConfig || {}
|
||||
const routerBase = ($config.app && $config.app.basePath) || '<%= router.base %>'
|
||||
if (!opts.path.startsWith('http') && (routerBase !== '/' && !opts.path.startsWith(routerBase))) {
|
||||
opts.path = joinURL(routerBase, opts.path)
|
||||
if (!fullPath.startsWith('http') && (routerBase !== '/' && !fullPath.startsWith(routerBase))) {
|
||||
fullPath = joinURL(routerBase, fullPath)
|
||||
}
|
||||
// Avoid loop redirect
|
||||
if (decodeURI(opts.path) === decodeURI(ssrContext.url)) {
|
||||
if (decodeURI(fullPath) === decodeURI(ssrContext.url)) {
|
||||
ssrContext.redirected = false
|
||||
return
|
||||
}
|
||||
ssrContext.res.writeHead(opts.status, {
|
||||
Location: normalizeURL(opts.path)
|
||||
Location: normalizeURL(fullPath)
|
||||
})
|
||||
ssrContext.res.end()
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
import { normalizeURL } from 'ufo'
|
||||
import { isSamePath as _isSamePath, joinURL, normalizeURL, withQuery, withoutTrailingSlash } from 'ufo'
|
||||
|
||||
// window.{{globals.loadedCallback}} hook
|
||||
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
|
||||
@ -219,7 +219,7 @@ export async function setContext (app, context) {
|
||||
status
|
||||
})
|
||||
} else {
|
||||
path = formatUrl(path, query)
|
||||
path = withQuery(path, query)
|
||||
if (process.server) {
|
||||
app.context.next({
|
||||
path,
|
||||
@ -594,86 +594,6 @@ function flags (options) {
|
||||
return options && options.sensitive ? '' : 'i'
|
||||
}
|
||||
|
||||
/**
|
||||
* Format given url, append query to url query string
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} query
|
||||
* @return {string}
|
||||
*/
|
||||
function formatUrl (url, query) {
|
||||
<% if (features.clientUseUrl) { %>
|
||||
url = new URL(url, top.location.href)
|
||||
for (const key in query) {
|
||||
const value = query[key]
|
||||
if (value == null) {
|
||||
continue
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
for (const arrayValue of value) {
|
||||
url.searchParams.append(key, arrayValue)
|
||||
}
|
||||
continue
|
||||
}
|
||||
url.searchParams.append(key, value)
|
||||
}
|
||||
url.searchParams.sort()
|
||||
return url.toString()
|
||||
<% } else { %>
|
||||
let protocol
|
||||
const index = url.indexOf('://')
|
||||
if (index !== -1) {
|
||||
protocol = url.substring(0, index)
|
||||
url = url.substring(index + 3)
|
||||
} else if (url.startsWith('//')) {
|
||||
url = url.substring(2)
|
||||
}
|
||||
|
||||
let parts = url.split('/')
|
||||
let result = (protocol ? protocol + '://' : '//') + parts.shift()
|
||||
|
||||
let path = parts.join('/')
|
||||
if (path === '' && parts.length === 1) {
|
||||
result += '/'
|
||||
}
|
||||
|
||||
let hash
|
||||
parts = path.split('#')
|
||||
if (parts.length === 2) {
|
||||
[path, hash] = parts
|
||||
}
|
||||
|
||||
result += path ? '/' + path : ''
|
||||
|
||||
if (query && JSON.stringify(query) !== '{}') {
|
||||
result += (url.split('?').length === 2 ? '&' : '?') + formatQuery(query)
|
||||
}
|
||||
result += hash ? '#' + hash : ''
|
||||
|
||||
return result
|
||||
<% } %>
|
||||
}
|
||||
<% if (!features.clientUseUrl) { %>
|
||||
/**
|
||||
* Transform data object to query string
|
||||
*
|
||||
* @param {object} query
|
||||
* @return {string}
|
||||
*/
|
||||
function formatQuery (query) {
|
||||
return Object.keys(query).sort().map((key) => {
|
||||
const val = query[key]
|
||||
if (val == null) {
|
||||
return ''
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
return val.slice().map(val2 => [key, '=', val2].join('')).join('&')
|
||||
}
|
||||
return key + '=' + val
|
||||
}).filter(Boolean).join('&')
|
||||
}
|
||||
<% } %>
|
||||
|
||||
export function addLifecycleHook(vm, hook, fn) {
|
||||
if (!vm.$options[hook]) {
|
||||
vm.$options[hook] = []
|
||||
@ -683,21 +603,11 @@ export function addLifecycleHook(vm, hook, fn) {
|
||||
}
|
||||
}
|
||||
|
||||
export function urlJoin () {
|
||||
return [].slice
|
||||
.call(arguments)
|
||||
.join('/')
|
||||
.replace(/\/+/g, '/')
|
||||
.replace(':/', '://')
|
||||
}
|
||||
export const urlJoin = joinURL
|
||||
|
||||
export function stripTrailingSlash (path) {
|
||||
return path.replace(/\/+$/, '') || '/'
|
||||
}
|
||||
export const stripTrailingSlash = withoutTrailingSlash
|
||||
|
||||
export function isSamePath (p1, p2) {
|
||||
return stripTrailingSlash(p1) === stripTrailingSlash(p2)
|
||||
}
|
||||
export const isSamePath = _isSamePath
|
||||
|
||||
export function setScrollRestoration (newVal) {
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user