1

在 PostgreSQL 的表中存储约 100 个 JPEG(每个 24K-100K)作为字节茶列。<img/>标签 src 属性引用 SvelteKit 端点:

<img src="/api/file/18.json" alt="Person"/>

收到此错误:

来自路由 /api/file/76.json 的无效响应:Uint8Array 主体必须伴随内容类型:application/octet-stream 标头

export async function get({ params }) {
  const { id } = params
  const sql = `SELECT _id, name, type, data FROM files WHERE _id = $1;`
  const { rows } = await db.query(sql, [id])
  const file = rows[0]
  return {
    headers: {
      'Content-disposition': `attachment; filename=${file.name}`,
      'Content-type': file.type
    },
    body: file.data
  }
}

由于SvelteKit 端点不与 req/res 对象交互,因为它们仅在某些平台上可用,我不能只将 bytea 值作为流写出到响应对象,但我不确定正确的方法是什么.

也试过这个SQL语句......

SELECT _id, name, type, encode(data, 'base64') as data FROM files WHERE _id = $1;

但这没有帮助。

有什么想法吗?

更新:问题可能与 SvelteKit 错误有关 - 请参阅https://github.com/sveltejs/kit/issues/1438

4

1 回答 1

1

SvelteKit 中的限制已于 6 月 11 日解决。我还需要将 file.data 放入一个新的 Uint8Array ...

// routes/api/file/[filenum].ts

import type { RequestHandler } from '@sveltejs/kit'
import { query } from '../_db'

export const get: RequestHandler = async ({ params }) => {
  const { filenum } = params
  const { rows } = await query(`SELECT * FROM find_file($1);`, [filenum])
  if (rows) {
    const file = rows[0]
    return {
      headers: {
        'Content-Disposition': `attachment; filename="${file.name}"`,
        'Content-Type': file.type
      },
      body: new Uint8Array(file.data)
    }
  } else return {
    status: 404
  }
}

这是 PostgreSQL 中 find_file() 函数的源代码:

CREATE OR REPLACE FUNCTION public.find_file(
    integer,
    OUT _id integer,
    OUT name character varying,
    OUT type character varying,
    OUT data bytea)
    RETURNS record
    LANGUAGE 'sql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$
SELECT _id, name, type, data FROM files WHERE _id = $1 LIMIT 1
$BODY$;

和查询()函数...

import pg from 'pg'

const pgNativePool = new pg.native.Pool({
  max: 10, // default
  connectionString: <string> import.meta.env.VITE_DATABASE_URL,
  ssl: {
    rejectUnauthorized: false
  }
})

type QueryResponse = (sql: string, params?: Array<any>) => Promise<pg.QueryResult<any>>
export const query: QueryResponse = (sql: string, params?: Array<any>) => pgNativePool.query(sql, params)
于 2021-09-04T17:00:34.373 回答