通过 link 在表单中自动填充网站标题

Autofill the title of website via link in a form

<form method="POST" action="{{ route('storeCompany') }}">
            @csrf
            <label>{{ __('Website URL') }}</label>
            <input type="text" name="url" value="{{ old('url') }}" placeholder="{{ __('http://example.com') }}" class="form-control" required="required">
            <label>{{ __('Website Title') }}</label>
            <input type="text" name="name" value="{{ old('name') }}" placeholder="{{ __('Example Ltd') }}" class="form-control" required="required">
            <input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="{{ __('Submit New Company') }}">
</form>

当用户键入“网站 URL”时,我希望“网站标题”字段为 auto-filled,而且如果用户愿意,“网站标题”必须是可编辑的。我怎样才能做到这一点?请帮助:(

示例:当用户在“网站 URL”字段中输入 https://whosebug.com/ URL 时,“网站标题”字段必须 auto-filled 为 Stack Overflow - Where Developers Learn, Share, &amp; Build Careers

方法如下:

  1. 阅读网站url。
  2. 向 codetabs api 发送 ajax 请求以获得完整 html。
  3. 从 html 中获取标题。
  4. 标题随心所欲。

function gettitle(website) {
  if(website.trim() == ''){
   return false;
  }
  var url = 'https://api.codetabs.com/v1/proxy/?quest=' + website;
  $.ajax({
    url: url,
    success: function(responseHtml) {
      var newTitle = $(responseHtml).filter('title').text();
      document.getElementById('title').innerHTML = 'Title: ' + newTitle
    },
    error: function() {
      document.getElementById('title').innerHTML = newTitle = 'Sorry that page doesn\'t';
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder='Website' oninput='gettitle(this.value)' type='url' id='url'>
<div id='title'></div>

用户输入数据后。

使用$("#text_field").val();

获取值

调用 ajax 并使用以下函数获取值,将 url 传递给 t

require 'simple_html_dom.php';
function dataParser($url){
    $html = new simple_html_dom();
    $html->load_file($url); 
    $title = $html->find('title',0)->innertext;
    return $title;
}
// something like $_GET['user_url'];
echo  $title = dataParser('https://whosebug.com');

这段代码会输出标题,把它设置到div你想显示标题的地方,像这样

var ajaxCallResponse = ""//store the response here
$("#title_div").val(ajaxCallResponse);

您在 url-field 元素上有一个 change 事件,该事件向 api 网站发出提取请求,该网站 return 的 html 内容该网站,然后它使用正则表达式提取 html 标题,然后将其添加到名称字段。

此外,在执行抓取时,我们会显示 Fetching 文本,让用户知道发生了什么。表单提交事件已被 preventDefault() 函数停止。在这里你可以在用户提交表单后做任何你想做的事。

不要使用 https://api.codetabs.com/v1/proxy/?quest= 来限制您的请求并向您显示 Too many requests 错误,您应该使用自己的代码来获取网站内容,然后 return 响应。要对此进行优化,您可以 return 仅网站标题,以节省带宽和 cpu 周期。

您需要 api 来获取网站内容的原因是因为 CORS。您不能只使用从您想要的任何网站获取资源。您只能从当前网站或允许您这样做的网站执行此操作。

document.addEventListener('submit', event => {
  event.preventDefault()
})

document.addEventListener('change', async (event) => {
  if (event.target.classList.contains('url-field')) {
    await changeUrl(event.target.closest('form').elements)
  }
})

async function changeUrl (fields) {
  try {
    if (!fields.url.value) return
    fields.output.removeAttribute('hidden')
    const response = await fetch('https://api.codetabs.com/v1/proxy/?quest=' + encodeURI(fields.url.value))
    const html = await response.text()
    const match = /<title[\s\S]*?>([\s\S]*?)<\/title>/gi.exec(html)
    if (!match || !match[1]) throw new Error('No title found')
    fields.name.value = match[1].trim()
    fields.output.setAttribute('hidden', '')
  } catch (error) {
    console.error(error)
  }
}
<form method="POST" action="">
<p>
  <label>Website URL</label>
  <input type="url" name="url" value="" placeholder="http://example.com" class="form-control url-field" required>
  <output name="output" hidden>Fetching</output>
</p>
<p>
  <label>Website Title</label>
  <input type="text" name="name" value="" placeholder="Example Ltd" class="form-control">
</p>
<input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="Submit New Company">
</form>

因为你的榜样看起来像 Laravel。 我发现在 PHP.

中写一个答案是合适的

example.blade.php

<title>{{ $title ?? 'Default title' }}</title>
<form method="POST" action="{{ route('storeCompany') }}">
    @csrf
    <label>{{ __('Website URL') }}</label>
    <input type="text" name="url" value="{{ $url ?? old('url') }}" placeholder="{{ __('http://example.com') }}" class="form-control" required="required">
    <label>{{ __('Website Title') }} <small>(Leave blank to retrieve from URL)</small></label>
    <input type="text" name="name" value="{{ $title ?? old('name') }}" placeholder="{{ __('Example Ltd') }}" class="form-control">
    <input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="{{ __('Submit New Company') }}">
</form>

CompanyController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class CompanyController extends Controller
{
    public function index(){
        
        return view('example');
    }
    
    public function storeCompany(Request $request){
        
        $title = $request->name;

        if (empty($title) && filter_var($request->url, FILTER_VALIDATE_URL)){
            $response = HTTP::get($request->url);
            if ($response->ok()){
                preg_match('/<title>(.*)<\/title>/i', $response->body(), $matches);
                $title = $matches[1] ?? null;
            }
        }

        $data = [
            'url' => $request->url,
            'title' => $title
        ];
        
        return view('example', $data);
    }
}