当前位置: 首页 > 知识库问答 >
问题:

无法从其他docker容器调用GET方法(HTTP 500)

爱繁
2023-03-14

当我试图使用url 127.0.0.1:8081/create将POST方法从第二个实例发送到第一个实例时,我收到HTTP 500。

我用的是Windows10。在本地运行服务器没有问题。POST方法非常有效。所以这意味着码头工人有问题,但我不知道在哪里。是CORS的问题吗?

下面是我的docker-compose.yml的第一个实例:

version: '3'

services:
    nginx:
        build:
            context: ./docker/nginx/
            dockerfile: Dockerfile-nginx
        volumes:
            - .:/var/www/symfony/
        ports:
            - 8080:80
            
    php:
        build:
            context: ./docker/php74/
            dockerfile: Dockerfile-php74
        volumes:
            - .:/var/www/symfony/
version: '3'

services:
    nginx:
        build:
            context: ./docker/nginx/
            dockerfile: Dockerfile-nginx
        volumes:
            - .:/var/www/symfony/
        ports:
            - 8081:80
            
    php:
        build:
            context: ./docker/php74/
            dockerfile: Dockerfile-php74
        volumes:
            - .:/var/www/symfony/
server {
    proxy_busy_buffers_size 512k;
    proxy_buffers 4 512k;
    proxy_buffer_size 256k;

    listen       80;
    server_name  localhost;
    root /var/www/symfony/public;

    location / {
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /index.php/$1 last;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        
         # https://enable-cors.org/server_nginx.html
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            #
            # Custom headers and headers various browsers *should* be OK with but aren't
            #
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            #
            # Tell client that this pre-flight info is valid for 20 days
            #
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        if ($request_method = 'POST') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }

        if ($request_method = 'GET') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }

    }

    error_log /dev/stdout info;
    access_log /var/log/nginx/symfony_access.log;
}

@edit:这是我的apicontroller.php,我正在调用其他服务器实例。

<?php

namespace App\Controller;

use App\Entity\Argument;
use App\Repository\ArgumentRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class ApiController extends AbstractController
{
    /**
     * @Route("/create", name="create_argument", methods={"POST"})
     */
    public function createArgument(Request $request, HttpClientInterface $client)
    {
        if (!strpos($request->headers->get('Content-Type'), 'application/json'))
        {
            $data = $request->toArray();
            $name = $data['name'];

            $response = $client->request(
                'POST',
                'http://127.0.0.1:8080/name',
                [
                    'headers' => [
                        'Content-Type' => 'application/json',
                        ],
                    'json' => ['name' => $name],
            ]);

            if ($response->getStatusCode() == 200)
            {
                $content = $response->toArray();
                $content['name'] = strrev($content['name']);

                $argument = new Argument();
                $argument->setName($content['name']);

                $entityManager = $this->getDoctrine()->getManager();
                $entityManager->persist($argument);
                $entityManager->flush();

                return new Response("Argument added", Response::HTTP_OK);
            }
        }

        return new Response("Bad request", Response::HTTP_BAD_REQUEST);
    }

    /**
     * @Route("/show", name="show_arguments", methods={"GET"})
     */
    public function showArguments(ArgumentRepository $repository)
    {
        $arguments = $repository->findAll();

        if (!$arguments)
            return new Response('There are no tasks.', Response::HTTP_NOT_FOUND);

        $encoders = [new XmlEncoder(), new JsonEncoder()];
        $normalizers = [new ObjectNormalizer()];
        $serializer = new Serializer($normalizers, $encoders);

        $content = $serializer->serialize($arguments, 'json');

        return new JsonResponse($content, Response::HTTP_CREATED, [], true);
    }
}

共有1个答案

子车鸿才
2023-03-14

当您通过容器内的Symfony HTTP客户端将请求发送到HTTP://127.0.0.1:8080/name时,IP127.0.0.1是第一个php容器的本地主机,而不是您的Windows主机。

第一个服务器实例对第二个服务器实例一无所知。

您应该在Windows中使用主机的IP,而不是127.0.0.1

$response = $client->request(
    'POST',
    'http://10.0.75.1:8080/name',
    [
        'headers' => [
            'Content-Type' => 'application/json',
         ],
        'json' => ['name' => $name],
    ]
);

查看如何获取主机的IP

此外,您还可以将2个docker-compose.yml文件合并为一个文件,这样您就可以在2个服务器实例之间拥有一个公共网络,并且每个实例都可以了解其他实例。

更新:您还可以为php服务添加hostname:hostname并使用hostname作为主机的URL。

version: '3'
services:
    nginx:
        build:
            context: ./docker/nginx/
            dockerfile: Dockerfile-nginx
        volumes:
            - .:/var/www/symfony/
        ports:
            - 8081:80
            
    php:
        build:
            context: ./docker/php74/
            dockerfile: Dockerfile-php74
        volumes:
            - .:/var/www/symfony/ 
        hostname: hostname
$response = $client->request(
    'POST',
    'http://hostname:8080/name',
    [
        'headers' => [
            'Content-Type' => 'application/json',
         ],
        'json' => ['name' => $name],
    ]
); 
 类似资料:
  • 所以我得到了两个都在同一activity的视图。我正在使用但是,我无法调用在uiview中定义的公共方法... 我对AndroidStudio还很陌生,我在这里发现的只是不同的类,而不是观点。 非常感谢!

  • 和DocerFile 很好笑因为...首先,我想把容器的名称“localhost”更改为另一个。但当我改变的时候,我不能运行Spring Bot应用程序,即使从IntelliJ。我在docker中创建了MySql的映像,并尝试在IntelliJ中进行连接。这是warking但当我想使用SpringBoot应用程序在caontainer然后是问题。我还没找到解决办法。我会非常感谢每一个帮助。 我在这

  • 问题内容: 我正在做作业,遇到了一些错误。在一个类中,我有此方法: 现在,我收到错误消息“无法从静态上下文中引用非静态方法…”,因此我将getPoints()设置为静态方法,并将变量也设置为静态,并且它可以正常工作。但是在另一种打印对象的方法中,它不起作用(我相信是由于static关键字)。 所以我的问题是,有没有一种方法可以在不创建第二个Class实例的情况下调用方法?这是我所拥有的一般构想代码

  • 我仍然是Java的新手,我正在努力使这个程序适合我的任务。 问题是: 杰夫在你家附近经营着一家当地的零售店。他已与您签订合同,让您创建一个交互式应用程序,以帮助他增加员工工资。创建一个名为 Details 的类,该类将包含员工 ID 号、名字、姓氏和薪水的获取和设置方法。包括一个名为getUpdateSalary()的方法,该方法将使员工的薪水增加10%。在您的主类中,包括一个名为 () 的静态方

  • 现在我得到错误“non-static method conly be referenced from a static context...”,所以我将getPoints()设置为静态方法,同时将变量设置为静态,这样就可以工作了。但是在另一个打印对象的方法中,它就不起作用了(我相信这是因为static关键字的缘故)。 那么我的问题是,在所有这些之后,有没有一种方法可以调用一个方法,而不创建第二个类