reecem / static-form
在 Laravel 应用中处理静态表单提交
Requires
- php: ^7.3|^8.0
- illuminate/contracts: ^7.0|^8.0
Requires (Dev)
- orchestra/testbench: ^6.0
- phpunit/phpunit: ^9.3
- vimeo/psalm: ^4.4
This package is auto-updated.
Last update: 2024-09-22 19:54:16 UTC
README
从 Next.JS 和 Netlify 或任何其他静态网站服务器内部处理您的 Laravel 应用中的静态表单提交。
安装
您可以通过 composer 安装此包
composer require reecem/static-form
要安装应用程序,您可以执行以下操作
php artisan static-form:install --provider --config
这将安装配置文件和服务提供者,但您可以单独选择每个文件,或者使用以下命令
您可以使用以下命令发布配置文件
php artisan vendor:publish --provider="ReeceM\StaticForm\StaticFormServiceProvider" --tag="static-form-config"
您可以使用以下命令发布服务提供者文件
php artisan vendor:publish --provider="ReeceM\StaticForm\StaticFormServiceProvider" --tag="static-form-provider"
您需要将以下内容添加到 config/app.php
文件中
/*
* Package Service Providers...
*/
+ App\Providers\StaticFormServiceProvider::class
您可以在此处查看文档 https://static-form.pkgpg.dev
使用方法
总体来说,当前版本的用法是您可以使用包中间件在您定义的控制器上,这将使用您的控制器来处理请求数据。
创建令牌
第一步是生成您的令牌,为此您可以使用控制台命令
php artisan static-form --refresh
这将生成您的令牌,它将在该会话期间仅显示纯文本版本。
另一种方法是调用 API 端点来生成新的令牌。API 通过 App\Providers\StaticFormServiceProvider::class
中定义的 Gate 进行安全保护
您可以在其中定义任何逻辑,允许仅授权人员访问应用程序。
要调用 API 端点,目前您可以通过自定义 UI 和 JavaScript 代码向端点发出请求。
URL 部分的 static-form
可以更改,它来自配置键 static-form.path
创建令牌的响应将是以下 JSON 格式,状态为 201
{ "plain_token": "random_string_that_is_40_characters_long", "message": "Token Created, please keep this as it is available once" }
- 制作插件 UI,决定它是包含在包中还是作为单独的片段。
使用中间件
要使用中间件,您可以使用配置文件定义一个路由,我建议您使用 API 端点,因为它无状态,并且不需要 CSRF 令牌。
// routes/api.php Route::group([ 'middleware' => config('static-form.middleware.forms'), ], function () { // A controller that you have created. Route::post('/contact', StaticContactController::class)->name('contact.create'); });
提交表单
在您的静态网站上,您可以拥有您的联系表单。处理表单的方式是通过主机提供商的 API 部分。
因此,对于 Vercel 应用程序,您可以在 api
目录下创建一个新文件。
对于代码的 API 部分
// api/contactus.js /** * Create a contact request to the main server. * * @param {http.IncomingMessage} req * @param {*} res */ import { APP_TOKEN, APP_URL } from "../../../lib/constants" export default async function contactus(req, res) { if (req.method !== 'POST') { return res.status(400); } if (req.body?.website) { return res.status(200); } let body = JSON.parse(req.body) let {_token, xsrf} = body.token; delete body.token const request = await fetch( `${APP_URL}/api/static-form/contactus`, { method: 'POST', body: JSON.stringify(body), headers: { 'X-STATIC-FORM': APP_TOKEN, 'Content-Type': 'application/json', 'Accept': 'application/json', "x-requested-with": "XMLHttpRequest", }, } ) if (request.status !== 201 ) { let json = await request.json() throw new Error(json.message || 'Failed to fetch API'); } const json = await request.json() if (json.errors) { console.error(json.errors) throw new Error('Failed to fetch API, json errors') } return res.status(201).json(json.data ?? {}); }
您可以为前端尝试一个简单的表单布局
import React, { useCallback, useEffect, useRef, useState } from 'react' const ContactUs = () => { const [contactName, setContactName] = useState('') const [contactEmail, setContactEmail] = useState('') const [honey, setHoney] = useState('') function handleForm(e) { e.preventDefault() if (honey.length >= 1) { return } let body = { name: contactName, email: contactEmail, } fetch( `${location.origin}/api/contactus`, { method: 'POST', body: JSON.stringify(body) } ) .then(response => { console.debug(response); }) .catch(error => { console.error(error) }) } return ( <> <form onSubmit={handleForm}> <div style={{marginBottom: '0.75rem'}}> <label htmlFor="name">Name</label> <input name="name" id="name" value={contactName} onChange={e => setContactName(e.target.value)} placeholder="Your Name" type="text" /> </div> <div style={{marginBottom: '0.75rem'}}> <label htmlFor="email">Email</label> <input name="email" id="email" value={contactEmail} onChange={e => setContactEmail(e.target.value)} placeholder="Your email" type="email" /> </div> <input style={{display: 'none'}} name="website" value={honey} onChange={e => setHoney(e.target.value)}> <!-- The honeypot field --> <button type="submit">Submit</button> </form> </> ) } export default ContactUs;
测试
测试目前正在进行中,有一些 :),我正在手动在实际应用程序中测试以确保它正常工作。
composer test
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG
贡献
有关详细信息,请参阅 CONTRIBUTING
安全漏洞
有关报告安全漏洞的详细信息,请参阅 我们的安全策略
鸣谢
许可证
MIT许可(MIT)。请参阅许可文件获取更多信息。