简体   繁体   English

如何以输入文件的形式获取我选择的文件的路径,以便我可以使用 cloudinary 上传服务器端

[英]How to get the path of the file I selected in a form of input file so I can upload with cloudinary the server side

I am able to get the filename of a file under the picture object as seen in the image below我能够获得图片 object 下的文件名,如下图所示目的

and I make a request to cloudinary with the following, but it says the image path is not correct, which makes sense, but the object I have for the chosen picture does not show the image path.我向 cloudinary 提出以下请求,但它说图像路径不正确,这是有道理的,但是我为所选图片拥有的 object 没有显示图像路径。

So how do I get the correct path for cloudinary.那么我如何获得云的正确路径。

var cloudinary = require("cloudinary").v2;

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

export default async function signup(req, res) {
  console.log(req.body);
  const body = req.body;

  cloudinary.uploader.upload(
    `${body}`,
    function (error, result) {
      console.log(result, error);
    }
  );

  try {
    const result = req.body;
    res.status(200).send(result);
  } catch (error) {
    console.error(error);
    res.status(error.requestResult.statusCode).send(error.message);
  }
}

Here is what I am sending to the api这是我发送给 api 的内容

 const res = await fetch("../api/image", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data.picture[0].name),
    });

    console.log(res);

I am using react hook forms, and here is the whole code for context我正在使用反应钩子 forms,这是上下文的完整代码

import { useForm, Controller } from "react-hook-form";
import Layout from "../components/Layout";
import ReactDatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { gql, useMutation } from "@apollo/client";
import useSWR from "swr";
import { useRouter } from "next/router";

const CREATE_DECOR_ENTRY = gql`
  mutation CreateDecorEntry(
    $ownerID: ID!
    $description: String!
    $pieces: Int!
    $purchaser: String!
    $alterations: Boolean!
    $cost: Int!
    $purchaseDate: Date!
    $category: String!
  ) {
    createDecor(
      data: {
        description: $description
        pieces: $pieces
        purchaser: $purchaser
        alterations: $alterations
        cost: $cost
        purchaseDate: $purchaseDate
        category: $category
        owner: { connect: $ownerID }
      }
    ) {
      description
    }
  }
`;

const fetcher = (url) => fetch(url).then((r) => r.json());
const fetchWithImage = (url, image) =>
  fetch(`${url}?image=${image}`).then((r) => r.json());

export default function Decor() {
  const { data: user, error: userError } = useSWR("/api/user", fetcher);

  const { data: cookieData, error: cookieError } = useSWR(
    "/api/cookie",
    fetcher
  );

  var cookieBearer = `Bearer ${cookieData}`;

  return (
    <Layout>
      <h1>Enter your Decor Data</h1>

      {user && cookieBearer && <Form user={user} cookieBearer={cookieBearer} />}
    </Layout>
  );
}

const Form = ({ cookieBearer, user }) => {
  const Router = useRouter();

  const [
    createDecorEntry,
    { data: createDecorEntryData, loading: saving },
  ] = useMutation(CREATE_DECOR_ENTRY, {
    context: {
      headers: {
        authorization: cookieBearer,
      },
    },
  });

  const { register, handleSubmit, errors, control } = useForm();
  const onSubmit = async (data) => {
    console.log(data);

    let yourDate = data.purchaseDate;

    const offset = yourDate.getTimezoneOffset();
    yourDate = new Date(yourDate.getTime() - offset * 60 * 1000);
    const date = yourDate.toISOString().split("T")[0];

    console.log(date);

    const dataMassage = {
      ...data,
      pieces: parseInt(data.pieces),
      cost: parseInt(data.cost),
      purchaseDate: date,
    };

    console.log(dataMassage);

    const res = await fetch("../api/image", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data.picture[0].name),
    });

    console.log(res);

    // const res = await createDecorEntry({
    //   variables: {
    //     ownerID: user.id,
    //     ...dataMassage,
    //   },
    // }).catch(console.error);

    // Router.push(`/decor/data`);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <h2>Image</h2>
        <input ref={register} type="file" name="picture" />
      </div>
      <div>
        <h2>Description</h2>
        <input
          type="text"
          placeholder="Description"
          name="description"
          ref={register({ required: true })}
        />
      </div>
      <div>
        <h2>Number of Pieces</h2>
        <input
          type="number"
          placeholder="Number of Pieces"
          name="pieces"
          ref={register({ required: true })}
        />
      </div>
      <div>
        <h2>Purchaser</h2>
        <input
          type="text"
          placeholder="Purchaser"
          name="purchaser"
          ref={register({ required: true })}
        />
      </div>
      <div>
        <h2>Alternations Needed</h2>
        <input
          type="checkbox"
          placeholder="Alternations Needed"
          name="alterations"
          ref={register({ required: true })}
        />
      </div>
      <div>
        <h2>Cost</h2>
        <input
          type="number"
          placeholder="Cost"
          name="cost"
          ref={register({ required: true })}
        />
      </div>
      <div>
        <h2>Purchase Date</h2>
        <Controller
          name="purchaseDate"
          control={control}
          render={({ onChange, value }) => (
            <ReactDatePicker selected={value} onChange={onChange} />
          )}
        />
      </div>
      <div>
        <h2>Category</h2>
        <select name="category" ref={register}>
          <option value="Curation">Curation</option>
          <option value=" Good"> Good</option>
        </select>
      </div>

      <div>
        <input type="submit" />
      </div>
    </form>
  );
};

According to documentation , you can't just upload file.根据文档,您不能只上传文件。 You will have to either save it somewhere first (for example locally on disk), or convert it into base64 .您必须先将其保存在某个地方(例如本地磁盘上),或者将其转换为 base64

Interestingly enough, other part of documentation suggests that you an send an array buffer , but I'm not sure if it is available in Node有趣的是,文档的其他部分建议您发送一个数组缓冲区,但我不确定它是否在 Node 中可用

I am only posting this answer so others can benefit, I ended up going the array buffer route.我只是发布这个答案,以便其他人可以受益,我最终选择了数组缓冲区路线。

import formidable from "formidable";
const cloudinary = require("cloudinary").v2;
const fs = require("fs");
const path = require("path");
let streamifier = require('streamifier');

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

// first we need to disable the default body parser
export const config = {
  api: {
    bodyParser: false,
  },
};

export default async function image(req, res) {
  

  try {

    const form = new formidable.IncomingForm();
  form.uploadDir = "./";
  form.keepExtensions = true;
  form.parse(req, (err, fields, files) => {
    console.log(JSON.stringify(files));

    console.log(files.image.path);

    var oldPath = files.image.path;
    var rawData = fs.readFileSync(oldPath);

    console.log(rawData);

    let cld_upload_stream = cloudinary.uploader.upload_stream(
      {
        folder: "sick-fits"
      },
      function(error, result) {
          console.log(error, result);
          res.status(200).send({ result });
      }
  );

  streamifier.createReadStream(rawData).pipe(cld_upload_stream);

  });

  } catch (error) {
    console.error(error);
    res.status(error.requestResult.statusCode).send(error.message);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当在反应或 html 中输入选择文件时,如何获取我的文件目录/文件路径 - how can I get my file directory / file path when file selected by input in react or html 如何获取 Finder 选择的文件的 posix 路径? - How can I get the posix path of a file that is selected by Finder? 我如何使用 g 脚本将文件上传到 cloudinary - How i upload file to cloudinary using g script 如何将文件 object 转换为填充的文件输入,以便我可以通过表单提交? - How do I convert a file object to a populated file input so I can submit via form? 如何从输入api获取文件的路径 - how can I get path of file from input api 如何在 reactjs 中上传文件并将文件的路径保存在 JSON 服务器中? - How can I upload a file in a reactjs and save the path to the file in the JSON server? 如何在输入文件中获取所选路径? - How to get the selected path in the input file? 如果是,我如何设置文件上传的路径 <input> 元素不可见,只能通过锚标记引用<a>?</a> - How can I set a path for a file to upload if an <input> element is not visible and only reference by an anchor tag <a>? 我可以在多文件上传中获取输入的值吗? - Can I get the value of an input in a multiple file upload? 我如何等待文件上传,以便我可以使用参数上传下一张图片 - How can i await for file to upload so i can upload next image with params
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM